summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx25
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mx25')
-rw-r--r--arch/arm/mach-mx25/Kconfig75
-rw-r--r--arch/arm/mach-mx25/Makefile16
-rw-r--r--arch/arm/mach-mx25/board-mx25_3stack.h175
-rw-r--r--arch/arm/mach-mx25/bus_freq.c102
-rw-r--r--arch/arm/mach-mx25/clock.c1674
-rw-r--r--arch/arm/mach-mx25/cpu.c63
-rw-r--r--arch/arm/mach-mx25/crm_regs.h249
-rw-r--r--arch/arm/mach-mx25/devices.c305
-rw-r--r--arch/arm/mach-mx25/dma.c663
-rw-r--r--arch/arm/mach-mx25/iomux.c199
-rw-r--r--arch/arm/mach-mx25/iomux.h233
-rw-r--r--arch/arm/mach-mx25/mm.c2
-rw-r--r--arch/arm/mach-mx25/mx25_3stack.c848
-rw-r--r--arch/arm/mach-mx25/mx25_3stack_cpld.c247
-rw-r--r--arch/arm/mach-mx25/mx25_3stack_gpio.c1367
-rw-r--r--arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c147
-rw-r--r--arch/arm/mach-mx25/mx25_pins.h250
-rw-r--r--arch/arm/mach-mx25/pm.c103
-rw-r--r--arch/arm/mach-mx25/sdma_script_code.h158
-rw-r--r--arch/arm/mach-mx25/serial.c332
-rw-r--r--arch/arm/mach-mx25/serial.h148
-rw-r--r--arch/arm/mach-mx25/system.c159
-rw-r--r--arch/arm/mach-mx25/usb.h103
-rw-r--r--arch/arm/mach-mx25/usb_dr.c138
-rw-r--r--arch/arm/mach-mx25/usb_h2.c88
25 files changed, 7819 insertions, 25 deletions
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
index 54d217314ee9..95f966a5fb1a 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -5,4 +5,79 @@ comment "MX25 platforms:"
config MACH_MX25_3DS
bool "Support MX25PDK (3DS) Platform"
+menu "MX25 Options"
+
+config MX25_OPTIONS
+ bool
+ default y
+ select CPU_ARM926T
+ select USB_ARCH_HAS_EHCI
+
+config MX25_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.
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA transfer"
+ depends on MXC_SDMA_API
+ help
+ Support Internal RAM as SDMA buffer or control structures
+
+config ARCH_MXC_HAS_NFC_V2
+ bool "MXC NFC Hardware Version 2"
+ depends on ARCH_MX25
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 2
+ 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 MX25 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX25 I2C2 module.
+
+config I2C_MXC_SELECT3
+ bool "Enable I2C3 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX25 I2C3 module.
+
+config FLEXCAN_MXC_SELECT1
+ bool "Enable FlexCAN1 module"
+ depends on CAN_FLEXCAN
+ help
+ Enable MX25 FlexCAN1 module.
+
+endmenu
+endmenu
endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
index 10cebc5ced8c..93e835c10107 100644
--- a/arch/arm/mach-mx25/Makefile
+++ b/arch/arm/mach-mx25/Makefile
@@ -1,3 +1,13 @@
-obj-y := mm.o devices.o
-obj-$(CONFIG_ARCH_MX25) += clock.o
-obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25pdk.o
+obj-y := system.o iomux.o cpu.o mm.o clock.o bus_freq.o devices.o serial.o
+
+obj-$(CONFIG_MXC_SDMA_API) += dma.o
+obj-$(CONFIG_SPI_MXC) += mx25_3stack_cpld.o
+obj-$(CONFIG_MACH_MX25_3DS) += mx25_3stack.o mx25_3stack_gpio.o mx25_3stack_pmic_mc34704.o
+
+obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o
+
+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-mx25/board-mx25_3stack.h b/arch/arm/mach-mx25/board-mx25_3stack.h
new file mode 100644
index 000000000000..ec2f9e95ab7b
--- /dev/null
+++ b/arch/arm/mach-mx25/board-mx25_3stack.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25_3STACK_H__
+#define __ASM_ARCH_MXC_BOARD_MX25_3STACK_H__
+
+#ifdef CONFIG_MACH_MX25_3DS
+
+/*!
+ * @defgroup BRDCFG_MX25 Board Configuration Options
+ * @ingroup MSL_MX25
+ */
+
+/*!
+ * @file mach-mx25/board-mx25_3stack.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX25 3STACK Platform.
+ *
+ * @ingroup BRDCFG_MX25
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+#include <linux/fsl_devices.h>
+
+/*!
+ * @name MXC UART board-level configurations
+ */
+/*! @{ */
+/* 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 0
+
+/* UART 4 configuration */
+#define UART4_MODE MODE_DTE
+#define UART4_IR NO_IRDA
+#define UART4_ENABLED 0
+
+/* 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)
+
+/*!
+ * @name debug board parameters
+ */
+/*! @{ */
+/*!
+ * Base address of debug board
+ */
+#define DEBUG_BASE_ADDRESS 0x78000000 /* Use a dummy base address */
+
+/* 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 0x20000
+
+/* LED switchs */
+#define LED_SWITCH_REG (BOARD_IO_ADDR + 0x00)
+/* buttons */
+#define SWITCH_BUTTON_REG (BOARD_IO_ADDR + 0x08)
+/* status, interrupt */
+#define INTR_STATUS_REG (BOARD_IO_ADDR + 0x10)
+#define INTR_RESET_REG (BOARD_IO_ADDR + 0x20)
+/*CPLD configuration*/
+#define CONFIG1_REG (BOARD_IO_ADDR + 0x28)
+#define CONFIG2_REG (BOARD_IO_ADDR + 0x30)
+/*interrupt mask */
+#define INTR_MASK_REG (BOARD_IO_ADDR + 0x38)
+
+/* 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)
+/* magic word for debug CPLD */
+#define MAGIC3_NUMBER3_REG (BOARD_IO_ADDR + 0x58)
+/* module reset register*/
+#define CONTROL_REG (BOARD_IO_ADDR + 0x60)
+/* CPU ID and Personality ID*/
+#define IDENT_REG (BOARD_IO_ADDR + 0x68)
+
+/* For interrupts like xuart, enet etc */
+#define EXPIO_PARENT_INT MX25_PIN_GPIO1_1
+
+#define EXPIO_INT_ENET_INT (MXC_BOARD_IRQ_START + 0)
+#define EXPIO_INT_XUARTA_INT (MXC_BOARD_IRQ_START + 1)
+#define EXPIO_INT_XUARTB_INT (MXC_BOARD_IRQ_START + 2)
+
+/*! 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 mx25_3stack_board_io;
+
+#define MXC_BD_LED1 (1 << 0)
+#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 MXC_DEFAULT_INTENSITY 127
+#define MXC_INTENSITY_OFF 0
+
+/*! @} */
+
+extern void mx25_3stack_gpio_init(void) __init;
+extern int headphone_det_status(void);
+extern void sgtl5000_enable_amp(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[];
+extern void mx2fb_set_brightness(uint8_t);
+extern int __init mx25_3stack_init_mc34704(void);
+extern void imx_adc_set_hsync(int on);
+
+#endif /* CONFIG_MACH_MX25_3DS */
+#endif /* __ASM_ARCH_MXC_BOARD_MX25_3STACK_H__ */
diff --git a/arch/arm/mach-mx25/bus_freq.c b/arch/arm/mach-mx25/bus_freq.c
new file mode 100644
index 000000000000..9c98e9f77582
--- /dev/null
+++ b/arch/arm/mach-mx25/bus_freq.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2009-2010 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 bus_freq.c
+ *
+ * @brief A common API for the Freescale Semiconductor i.MXC CPUfreq module
+ * and DVFS CORE module.
+ *
+ * The APIs are for setting bus frequency to low or high.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+int low_bus_freq_mode;
+int high_bus_freq_mode;
+char *gp_reg_id = "REG3_CORE";
+
+int set_low_bus_freq(void)
+{
+ return 0;
+}
+
+int set_high_bus_freq(int high_bus_freq)
+{
+ return 0;
+}
+
+int low_freq_bus_used(void)
+{
+ return 0;
+}
+
+/*!
+ * This is the probe routine for the bus frequency driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit busfreq_probe(struct platform_device *pdev)
+{
+ low_bus_freq_mode = 0;
+ high_bus_freq_mode = 0;
+
+ return 0;
+}
+
+static struct platform_driver busfreq_driver = {
+ .driver = {
+ .name = "busfreq",
+ },
+ .probe = busfreq_probe,
+};
+
+/*!
+ * Initialise the busfreq_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init busfreq_init(void)
+{
+ if (platform_driver_register(&busfreq_driver) != 0) {
+ printk(KERN_ERR "busfreq_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "Bus freq driver module loaded\n");
+ return 0;
+}
+
+static void __exit busfreq_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&busfreq_driver);
+}
+
+module_init(busfreq_init);
+module_exit(busfreq_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("BusFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
index 155014993b13..d9723cc7cf47 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-mx25/clock.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ * Copyright (C) 2008-2010 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -16,6 +17,8 @@
* MA 02110-1301, USA.
*/
+#include <linux/module.h>
+#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
@@ -28,6 +31,7 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/mx25.h>
+#include "crm_regs.h"
#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
@@ -52,6 +56,1515 @@
#define CCM_LTR2 0x48
#define CCM_LTR3 0x4c
+#define OSC24M_CLK_FREQ 24000000 /* 24M reference clk */
+#define OSC32K_CLK_FREQ 32768 /* 32.768k oscillator in */
+
+#if defined CONFIG_CPU_FREQ_IMX
+#define AHB_CLK_DEFAULT 133000000
+#define ARM_SRC_DEFAULT 532000000
+#endif
+
+static struct clk mpll_clk;
+static struct clk upll_clk;
+static struct clk ahb_clk;
+static struct clk upll_24610k_clk;
+int cpu_wp_nr;
+
+static int clk_cgcr_enable(struct clk *clk);
+static void clk_cgcr_disable(struct clk *clk);
+static unsigned long get_rate_ipg(struct clk *clk);
+
+static int _clk_upll_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_CCTL);
+ reg &= ~MXC_CCM_CCTL_UPLL_DISABLE;
+ __raw_writel(reg, MXC_CCM_CCTL);
+
+ while ((__raw_readl(MXC_CCM_UPCTL) & MXC_CCM_UPCTL_LF) == 0)
+ ;
+
+ return 0;
+}
+
+static void _clk_upll_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_CCTL);
+ reg |= MXC_CCM_CCTL_UPLL_DISABLE;
+ __raw_writel(reg, MXC_CCM_CCTL);
+}
+
+static int _perclk_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_CGCR0);
+ reg |= 1 << clk->id;
+ __raw_writel(reg, MXC_CCM_CGCR0);
+
+ return 0;
+}
+
+static void _perclk_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_CGCR0);
+ reg &= ~(1 << clk->id);
+ __raw_writel(reg, MXC_CCM_CGCR0);
+}
+
+static unsigned long _clk_osc24m_get_rate(struct clk *clk)
+{
+ return OSC24M_CLK_FREQ;
+}
+
+static unsigned long _clk_osc32k_get_rate(struct clk *clk)
+{
+ return OSC32K_CLK_FREQ;
+}
+
+static unsigned long _clk_pll_get_rate(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_get_rate(clk->parent);
+
+ if (clk == &mpll_clk) {
+ reg = __raw_readl(MXC_CCM_MPCTL);
+ pdf = (reg & MXC_CCM_MPCTL_PD_MASK) >> MXC_CCM_MPCTL_PD_OFFSET;
+ mfd =
+ (reg & MXC_CCM_MPCTL_MFD_MASK) >> MXC_CCM_MPCTL_MFD_OFFSET;
+ mfi =
+ (reg & MXC_CCM_MPCTL_MFI_MASK) >> MXC_CCM_MPCTL_MFI_OFFSET;
+ mfn =
+ (reg & MXC_CCM_MPCTL_MFN_MASK) >> MXC_CCM_MPCTL_MFN_OFFSET;
+ } else if (clk == &upll_clk) {
+ reg = __raw_readl(MXC_CCM_UPCTL);
+ pdf = (reg & MXC_CCM_UPCTL_PD_MASK) >> MXC_CCM_UPCTL_PD_OFFSET;
+ mfd =
+ (reg & MXC_CCM_UPCTL_MFD_MASK) >> MXC_CCM_UPCTL_MFD_OFFSET;
+ mfi =
+ (reg & MXC_CCM_UPCTL_MFI_MASK) >> MXC_CCM_UPCTL_MFI_OFFSET;
+ mfn =
+ (reg & MXC_CCM_UPCTL_MFN_MASK) >> MXC_CCM_UPCTL_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);
+
+ return temp;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
+{
+ int div = clk_get_rate(clk->parent) / rate;
+
+ if (clk_get_rate(clk->parent) % rate)
+ div++;
+
+ if (div > 4)
+ div = 4;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long div = 0x0, reg = 0x0;
+ unsigned long cctl = __raw_readl(MXC_CCM_CCTL);
+
+#if defined CONFIG_CPU_FREQ_IMX
+ struct cpu_wp *cpu_wp;
+ unsigned long ahb_clk_div = 0;
+ unsigned long arm_src = 0;
+ int i;
+
+ cpu_wp = get_cpu_wp(&cpu_wp_nr);
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (cpu_wp[i].cpu_rate == rate) {
+ div = cpu_wp[i].cpu_podf;
+ ahb_clk_div = cpu_wp[i].cpu_rate / AHB_CLK_DEFAULT - 1;
+ arm_src =
+ (cpu_wp[i].pll_rate == ARM_SRC_DEFAULT) ? 0 : 1;
+ break;
+ }
+ }
+ if (i == cpu_wp_nr)
+ return -EINVAL;
+ reg = (cctl & ~MXC_CCM_CCTL_ARM_MASK) |
+ (div << MXC_CCM_CCTL_ARM_OFFSET);
+ reg = (reg & ~MXC_CCM_CCTL_AHB_MASK) |
+ (ahb_clk_div << MXC_CCM_CCTL_AHB_OFFSET);
+ reg = (reg & ~MXC_CCM_CCTL_ARM_SRC) |
+ (arm_src << MXC_CCM_CCTL_ARM_SRC_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCTL);
+#else
+ div = clk_get_rate(clk->parent) / rate;
+
+ if (div > 4 || div < 1 || ((clk_get_rate(clk->parent) / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg =
+ (cctl & ~MXC_CCM_CCTL_ARM_MASK) | (div << MXC_CCM_CCTL_ARM_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCTL);
+#endif
+
+ return 0;
+}
+
+static unsigned long _clk_cpu_get_rate(struct clk *clk)
+{
+ unsigned long div;
+ unsigned long cctl = __raw_readl(MXC_CCM_CCTL);
+ unsigned long rate;
+
+ div = (cctl & MXC_CCM_CCTL_ARM_MASK) >> MXC_CCM_CCTL_ARM_OFFSET;
+
+ rate = clk_get_rate(clk->parent) / (div + 1);
+
+ if (cctl & MXC_CCM_CCTL_ARM_SRC) {
+ rate *= 3;
+ rate /= 4;
+ }
+
+ return rate;
+}
+
+static unsigned long _clk_ahb_get_rate(struct clk *clk)
+{
+ unsigned long div;
+ unsigned long cctl = __raw_readl(MXC_CCM_CCTL);
+
+ div = (cctl & MXC_CCM_CCTL_AHB_MASK) >> MXC_CCM_CCTL_AHB_OFFSET;
+
+ return clk_get_rate(clk->parent) / (div + 1);
+}
+
+static void *pcdr_a[4] = {
+ MXC_CCM_PCDR0, MXC_CCM_PCDR1, MXC_CCM_PCDR2, MXC_CCM_PCDR3
+};
+static unsigned long _clk_perclkx_get_rate(struct clk *clk)
+{
+ unsigned long perclk_pdf;
+ unsigned long pcdr;
+
+ pcdr = __raw_readl(pcdr_a[clk->id >> 2]);
+
+ perclk_pdf =
+ (pcdr >> ((clk->id & 3) << 3)) & MXC_CCM_PCDR1_PERDIV1_MASK;
+
+ return clk_get_rate(clk->parent) / (perclk_pdf + 1);
+}
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long reg;
+ unsigned long div;
+ unsigned long parent_rate;
+
+ if (clk->id < 0 || clk->id > 15)
+ return -EINVAL;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg =
+ __raw_readl(pcdr_a[clk->id >> 2]) & ~(MXC_CCM_PCDR1_PERDIV1_MASK <<
+ ((clk->id & 3) << 3));
+ reg |= div << ((clk->id & 3) << 3);
+ __raw_writel(reg, pcdr_a[clk->id >> 2]);
+
+ return 0;
+}
+
+static int _clk_perclkx_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long mcr;
+
+ if (parent != &upll_clk && parent != &ahb_clk)
+ return -EINVAL;
+
+ clk->parent = parent;
+ mcr = __raw_readl(MXC_CCM_MCR);
+ if (parent == &upll_clk)
+ mcr |= (1 << clk->id);
+ else
+ mcr &= ~(1 << clk->id);
+
+ __raw_writel(mcr, MXC_CCM_MCR);
+
+ return 0;
+}
+
+static int _clk_perclkx_set_parent3(struct clk *clk, struct clk *parent)
+{
+ unsigned long mcr = __raw_readl(MXC_CCM_MCR);
+ int bit;
+
+ if (parent != &upll_clk && parent != &ahb_clk &&
+ parent != &upll_24610k_clk)
+ return -EINVAL;
+
+ switch (clk->id) {
+ case 2:
+ bit = MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET;
+ break;
+ case 13:
+ bit = MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET;
+ break;
+ case 14:
+ bit = MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (parent == &upll_24610k_clk) {
+ mcr |= 1 << bit;
+ __raw_writel(mcr, MXC_CCM_MCR);
+ clk->parent = parent;
+ } else {
+ mcr &= ~(1 << bit);
+ __raw_writel(mcr, MXC_CCM_MCR);
+ return _clk_perclkx_set_parent(clk, parent);
+ }
+
+ return 0;
+}
+
+static unsigned long _clk_ipg_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2; /* Always AHB / 2 */
+}
+
+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)
+{
+ return clk->parent->set_rate(clk->parent, rate);
+}
+
+/* Top-level clocks */
+
+static struct clk osc24m_clk = {
+ .get_rate = _clk_osc24m_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk osc32k_clk = {
+ .get_rate = _clk_osc32k_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk mpll_clk = {
+ .parent = &osc24m_clk,
+ .get_rate = _clk_pll_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk upll_clk = {
+ .parent = &osc24m_clk,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_upll_enable,
+ .disable = _clk_upll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_24610k_get_rate(struct clk *clk)
+{
+ long long temp = clk_get_rate(clk->parent) * 2461LL;
+
+ do_div(temp, 24000);
+
+ return temp; /* Always (UPLL * 24.61 / 240) */
+}
+
+static struct clk upll_24610k_clk = {
+ .parent = &upll_clk,
+ .get_rate = _clk_24610k_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+/* Mid-level clocks */
+
+static struct clk cpu_clk = { /* ARM clock */
+ .parent = &mpll_clk,
+ .set_rate = _clk_cpu_set_rate,
+ .get_rate = _clk_cpu_get_rate,
+ .round_rate = _clk_cpu_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ahb_clk = { /* a.k.a. HCLK */
+ .parent = &cpu_clk,
+ .get_rate = _clk_ahb_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ipg_clk = {
+ .parent = &ahb_clk,
+ .get_rate = _clk_ipg_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+
+/* Bottom-level clocks */
+
+struct clk usb_ahb_clk = {
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk rtic_clk = {
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_RTIC_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk emi_clk = {
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_EMI_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk brom_clk = {
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_BROM_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+static struct clk per_clk[] = {
+ /* per_csi_clk */
+ {
+ .id = 0,
+ .parent = &upll_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_epit_clk */
+ {
+ .id = 1,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_esai_clk */
+ {
+ .id = 2,
+ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent3,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_esdhc1_clk */
+ {
+ .id = 3,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_esdhc2_clk */
+ {
+ .id = 4,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_gpt_clk */
+ {
+ .id = 5,
+ .parent = &ahb_clk, /* Must be AHB */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_i2c_clk */
+ {
+ .id = 6,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_lcdc_clk */
+ {
+ .id = 7,
+ .parent = &upll_clk, /* Must be UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_nfc_clk */
+ {
+ .id = 8,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_owire_clk */
+ {
+ .id = 9,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_pwm_clk */
+ {
+ .id = 10,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_sim1_clk */
+ {
+ .id = 11,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_sim2_clk */
+ {
+ .id = 12,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_ssi1_clk */
+ {
+ .id = 13,
+ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent3,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_ssi2_clk */
+ {
+ .id = 14,
+ .parent = &ahb_clk, /* can be AHB or UPLL or 24.61MHz */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent3,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,
+ },
+ /* per_uart_clk */
+ {
+ .id = 15,
+ .parent = &ahb_clk, /* can be AHB or UPLL */
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .set_parent = _clk_perclkx_set_parent,
+ .get_rate = _clk_perclkx_get_rate,
+ .enable = _perclk_enable,
+ .disable = _perclk_disable,
+ .flags = RATE_PROPAGATES,},
+};
+
+struct clk nfc_clk = {
+ .id = 0,
+ .parent = &per_clk[8],
+};
+
+struct clk audmux_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_AUDMUX_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk ata_clk[] = {
+ {
+ /* ata_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_ATA_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &ata_clk[1],},
+ {
+ /* ata_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_ATA_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk can_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CAN1_OFFSET,
+ .disable = clk_cgcr_disable,},
+ {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CAN2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk csi_clk[] = {
+ {
+ /* csi_clk */
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &csi_clk[1],},
+ {
+ /* csi_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CSI_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &csi_clk[2],},
+ {
+ /* csi_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_CSI_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk cspi_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CSPI1_OFFSET,
+ .get_rate = get_rate_ipg,
+ .disable = clk_cgcr_disable,},
+ {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CSPI2_OFFSET,
+ .get_rate = get_rate_ipg,
+ .disable = clk_cgcr_disable,},
+ {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_CSPI3_OFFSET,
+ .get_rate = get_rate_ipg,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk dryice_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_DRYICE_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk ect_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_ECT_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk epit1_clk[] = {
+ {
+ /* epit_clk */
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &epit1_clk[1],},
+ {
+ /* epit_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_EPIT1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk epit2_clk[] = {
+ {
+ /* epit_clk */
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &epit2_clk[1],},
+ {
+ /* epit_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_EPIT2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk esai_clk[] = {
+ {
+ /* esai_clk */
+ .id = 0,
+ .parent = &per_clk[2],
+ .secondary = &esai_clk[1],},
+ {
+ /* esai_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_ESAI_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &esai_clk[2],},
+ {
+ /* esai_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_ESAI_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk esdhc1_clk[] = {
+ {
+ /* esdhc_clk */
+ .id = 0,
+ .parent = &per_clk[3],
+ .secondary = &esdhc1_clk[1],},
+ {
+ /* esdhc_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_ESDHC1_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &esdhc1_clk[2],},
+ {
+ /* esdhc_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk esdhc2_clk[] = {
+ {
+ /* esdhc_clk */
+ .id = 1,
+ .parent = &per_clk[4],
+ .secondary = &esdhc2_clk[1],},
+ {
+ /* esdhc_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_ESDHC2_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &esdhc2_clk[2],},
+ {
+ /* esdhc_ahb_clk */
+ .id = 1,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk fec_clk[] = {
+ {
+ /* fec_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_FEC_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &fec_clk[1],},
+ {
+ /* fec_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_FEC_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk gpio_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPIO1_OFFSET,
+ .disable = clk_cgcr_disable,},
+ {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPIO2_OFFSET,
+ .disable = clk_cgcr_disable,},
+ {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPIO3_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+static struct clk gpt1_clk[] = {
+ {
+ /* gpt_clk */
+ .id = 0,
+ .parent = &per_clk[5],
+ .secondary = &gpt1_clk[1],},
+ {
+ /* gpt_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPT1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+static struct clk gpt2_clk[] = {
+ {
+ /* gpt_clk */
+ .id = 1,
+ .parent = &per_clk[5],
+ .secondary = &gpt1_clk[1],},
+ {
+ /* gpt_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPT2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+static struct clk gpt3_clk[] = {
+ {
+ /* gpt_clk */
+ .id = 2,
+ .parent = &per_clk[5],
+ .secondary = &gpt1_clk[1],},
+ {
+ /* gpt_ipg_clk */
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPT3_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+static struct clk gpt4_clk[] = {
+ {
+ /* gpt_clk */
+ .id = 3,
+ .parent = &per_clk[5],
+ .secondary = &gpt1_clk[1],},
+ {
+ /* gpt_ipg_clk */
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_GPT4_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk i2c_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[6],},
+ {
+ .id = 1,
+ .parent = &per_clk[6],},
+ {
+ .id = 2,
+ .parent = &per_clk[6],},
+};
+
+struct clk iim_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_IIM_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk iomuxc_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_IOMUXC_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk kpp_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_KPP_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk lcdc_clk[] = {
+ {
+ /* lcdc_clk */
+ .id = 0,
+ .parent = &per_clk[7],
+ .secondary = &lcdc_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,},
+ {
+ /* lcdc_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_LCDC_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &lcdc_clk[2],},
+ {
+ /* lcdc_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_LCDC_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk owire_clk[] = {
+ {
+ /* owire_clk */
+ .id = 0,
+ .parent = &per_clk[9],
+ .secondary = &owire_clk[1],},
+ {
+ /* owire_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_OWIRE_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk pwm1_clk[] = {
+ {
+ /* pwm_clk */
+ .id = 0,
+ .parent = &per_clk[10],
+ .secondary = &pwm1_clk[1],},
+ {
+ /* pwm_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR1,
+ .enable_shift = MXC_CCM_CGCR1_PWM1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk pwm2_clk[] = {
+ {
+ /* pwm_clk */
+ .id = 1,
+ .parent = &per_clk[10],
+ .secondary = &pwm2_clk[1],},
+ {
+ /* pwm_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_PWM2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk pwm3_clk[] = {
+ {
+ /* pwm_clk */
+ .id = 2,
+ .parent = &per_clk[10],
+ .secondary = &pwm3_clk[1],},
+ {
+ /* pwm_ipg_clk */
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk pwm4_clk[] = {
+ {
+ /* pwm_clk */
+ .id = 3,
+ .parent = &per_clk[10],
+ .secondary = &pwm4_clk[1],},
+ {
+ /* pwm_ipg_clk */
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_PWM3_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk rng_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_RNGB_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk scc_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SCC_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk sdma_clk[] = {
+ {
+ /* sdma_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SDMA_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &sdma_clk[1],},
+ {
+ /* sdma_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_SDMA_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk sim1_clk[] = {
+ {
+ /* sim1_clk */
+ .id = 0,
+ .parent = &per_clk[11],
+ .secondary = &sim1_clk[1],},
+ {
+ /* sim_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SIM1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk sim2_clk[] = {
+ {
+ /* sim2_clk */
+ .id = 1,
+ .parent = &per_clk[12],
+ .secondary = &sim2_clk[1],},
+ {
+ /* sim_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SIM2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk slcdc_clk[] = {
+ {
+ /* slcdc_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SLCDC_OFFSET,
+ .disable = clk_cgcr_disable,
+ .secondary = &slcdc_clk[1],},
+ {
+ /* slcdc_ahb_clk */
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR0,
+ .enable_shift = MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk spba_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SPBA_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk ssi1_clk[] = {
+ {
+ /* ssi_clk */
+ .id = 0,
+ .parent = &per_clk[13],
+ .secondary = &ssi1_clk[1],},
+ {
+ /* ssi_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SSI1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk ssi2_clk[] = {
+ {
+ /* ssi_clk */
+ .id = 1,
+ .parent = &per_clk[14],
+ .secondary = &ssi2_clk[1],},
+ {
+ /* ssi_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_SSI2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk tsc_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_TCHSCRN_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+struct clk uart1_clk[] = {
+ {
+ /* uart_clk */
+ .id = 0,
+ .parent = &per_clk[15],
+ .secondary = &uart1_clk[1],},
+ {
+ /* uart_ipg_clk */
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_UART1_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk uart2_clk[] = {
+ {
+ /* uart_clk */
+ .id = 1,
+ .parent = &per_clk[15],
+ .secondary = &uart2_clk[1],},
+ {
+ /* uart_ipg_clk */
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_UART2_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk uart3_clk[] = {
+ {
+ /* uart_clk */
+ .id = 2,
+ .parent = &per_clk[15],
+ .secondary = &uart3_clk[1],},
+ {
+ /* uart_ipg_clk */
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_UART3_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk uart4_clk[] = {
+ {
+ /* uart_clk */
+ .id = 3,
+ .parent = &per_clk[15],
+ .secondary = &uart4_clk[1],},
+ {
+ /* uart_ipg_clk */
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_UART4_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk uart5_clk[] = {
+ {
+ /* uart_clk */
+ .id = 4,
+ .parent = &per_clk[15],
+ .secondary = &uart5_clk[1],},
+ {
+ /* uart_ipg_clk */
+ .id = 4,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_UART5_OFFSET,
+ .disable = clk_cgcr_disable,},
+};
+
+struct clk wdog_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_CGCR2,
+ .enable_shift = MXC_CCM_CGCR2_WDOG_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
+static unsigned long _clk_usb_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 64)
+ return -EINVAL;
+
+ return parent_rate / div;
+}
+
+static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long reg;
+ unsigned long div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+
+ if (parent_rate / div != rate)
+ return -EINVAL;
+ if (div > 64)
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCTL) & ~MXC_CCM_CCTL_USB_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_CCTL_USB_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCTL);
+
+ return 0;
+}
+
+static unsigned long _clk_usb_get_rate(struct clk *clk)
+{
+ unsigned long div =
+ __raw_readl(MXC_CCM_CCTL) & MXC_CCM_CCTL_USB_DIV_MASK;
+
+ div >>= MXC_CCM_CCTL_USB_DIV_OFFSET;
+
+ return clk_get_rate(clk->parent) / (div + 1);
+}
+
+static int _clk_usb_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long mcr;
+
+ if (parent != &upll_clk && parent != &ahb_clk)
+ return -EINVAL;
+
+ clk->parent = parent;
+ mcr = __raw_readl(MXC_CCM_MCR);
+ if (parent == &ahb_clk)
+ mcr |= (1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET);
+ else
+ mcr &= ~(1 << MXC_CCM_MCR_USB_CLK_MUX_OFFSET);
+
+ __raw_writel(mcr, MXC_CCM_MCR);
+
+ return 0;
+}
+
+static struct clk usb_clk = {
+ .parent = &upll_clk,
+ .get_rate = _clk_usb_get_rate,
+ .set_rate = _clk_usb_set_rate,
+ .round_rate = _clk_usb_round_rate,
+ .set_parent = _clk_usb_set_parent,
+};
+
+/* CLKO */
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 64)
+ return -EINVAL;
+
+ return parent_rate / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long reg;
+ unsigned long div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+ if (div > 64)
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_MCR_CLKO_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_MCR);
+
+ return 0;
+}
+
+static unsigned long _clk_clko_get_rate(struct clk *clk)
+{
+ unsigned long div =
+ __raw_readl(MXC_CCM_MCR) & MXC_CCM_MCR_CLKO_DIV_MASK;
+
+ div >>= MXC_CCM_MCR_CLKO_DIV_OFFSET;
+
+ return clk_get_rate(clk->parent) / (div + 1);
+}
+
+static struct clk *clko_sources[] = {
+ &osc32k_clk, /* 0x0 */
+ &osc24m_clk, /* 0x1 */
+ &cpu_clk, /* 0x2 */
+ &ahb_clk, /* 0x3 */
+ &ipg_clk, /* 0x4 */
+ NULL, /* 0x5 */
+ NULL, /* 0x6 */
+ NULL, /* 0x7 */
+ NULL, /* 0x8 */
+ NULL, /* 0x9 */
+ &per_clk[0], /* 0xA */
+ &per_clk[2], /* 0xB */
+ &per_clk[13], /* 0xC */
+ &per_clk[14], /* 0xD */
+ &usb_clk, /* 0xE */
+ NULL, /* 0xF */
+};
+
+#define NR_CLKO_SOURCES (sizeof(clko_sources) / sizeof(struct clk *))
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long reg =
+ __raw_readl(MXC_CCM_MCR) & ~MXC_CCM_MCR_CLKO_SEL_MASK;
+ struct clk **src;
+ int i;
+
+ for (i = 0, src = clko_sources; i < NR_CLKO_SOURCES; i++, src++)
+ if (*src == parent)
+ break;
+
+ if (i == NR_CLKO_SOURCES)
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ reg |= i << MXC_CCM_MCR_CLKO_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_MCR);
+
+ return 0;
+}
+
+static struct clk clko_clk = {
+ .get_rate = _clk_clko_get_rate,
+ .set_rate = _clk_clko_set_rate,
+ .round_rate = _clk_clko_round_rate,
+ .set_parent = _clk_clko_set_parent,
+ .enable = clk_cgcr_enable,
+ .enable_reg = MXC_CCM_MCR,
+ .enable_shift = MXC_CCM_MCR_CLKO_EN_OFFSET,
+ .disable = clk_cgcr_disable,
+};
+
static unsigned long get_rate_mpll(void)
{
ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
@@ -59,12 +1572,14 @@ static unsigned long get_rate_mpll(void)
return mxc_decode_pll(mpctl, 24000000);
}
+# if 0
static unsigned long get_rate_upll(void)
{
ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
return mxc_decode_pll(mpctl, 24000000);
}
+#endif
unsigned long get_rate_arm(struct clk *clk)
{
@@ -89,6 +1604,7 @@ static unsigned long get_rate_ipg(struct clk *clk)
return get_rate_ahb(NULL) >> 1;
}
+#if 0
static unsigned long get_rate_per(int per)
{
unsigned long ofs = (per & 0x3) * 8;
@@ -133,6 +1649,7 @@ static unsigned long get_rate_otg(struct clk *clk)
{
return 48000000; /* FIXME */
}
+#endif
static int clk_cgcr_enable(struct clk *clk)
{
@@ -154,6 +1671,7 @@ static void clk_cgcr_disable(struct clk *clk)
__raw_writel(reg, clk->enable_reg);
}
+#if 0
#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
static struct clk name = { \
.id = i, \
@@ -191,6 +1709,7 @@ DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
+#endif
#define _REGISTER_CLOCK(d, n, c) \
{ \
@@ -200,6 +1719,7 @@ DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
},
static struct clk_lookup lookups[] = {
+#if 0
_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
@@ -225,24 +1745,174 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+#endif
+ _REGISTER_CLOCK(NULL, "osc24m_clk", osc24m_clk)
+ _REGISTER_CLOCK(NULL, "osc32k_clk", osc32k_clk)
+ _REGISTER_CLOCK(NULL, "mpll_clk", mpll_clk)
+ _REGISTER_CLOCK(NULL, "upll_clk", upll_clk)
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
+ _REGISTER_CLOCK(NULL, "ahb_clk", ahb_clk)
+ _REGISTER_CLOCK(NULL, "ipg_clk", ipg_clk)
+ _REGISTER_CLOCK(NULL, "usb_ahb_clk", usb_ahb_clk)
+ _REGISTER_CLOCK("mxcintuart.0", NULL, uart1_clk[0])
+ _REGISTER_CLOCK("mxcintuart.1", NULL, uart2_clk[0])
+ _REGISTER_CLOCK("mxcintuart.2", NULL, uart3_clk[0])
+ _REGISTER_CLOCK("mxcintuart.3", NULL, uart4_clk[0])
+ _REGISTER_CLOCK("mxcintuart.4", NULL, uart5_clk[0])
+ _REGISTER_CLOCK(NULL, "usb_ahb_clk", usb_ahb_clk)
+ _REGISTER_CLOCK(NULL, "usb_clk", usb_clk)
+ _REGISTER_CLOCK("mxc_nandv2_flash.0", NULL, nfc_clk)
+ _REGISTER_CLOCK("spi_imx.0", NULL, cspi_clk[0])
+ _REGISTER_CLOCK("spi_imx.1", NULL, cspi_clk[1])
+ _REGISTER_CLOCK("spi_imx.2", NULL, cspi_clk[2])
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk[0])
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk[0])
+ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk[0])
+ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk[0])
+ _REGISTER_CLOCK("mxc_keypad.0", NULL, kpp_clk)
+ _REGISTER_CLOCK("imx_adc.0", NULL, tsc_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk[0])
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1])
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2])
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk[0])
+ _REGISTER_CLOCK(NULL, "dryice_clk", dryice_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
+ _REGISTER_CLOCK("mxc_sdma.0", "sdma_ipg_clk", sdma_clk[0])
+ _REGISTER_CLOCK("mxc_sdma.0", "sdma_ahb_clk", sdma_clk[1])
+ _REGISTER_CLOCK("mxsdhci.0", NULL, esdhc1_clk[0])
+ _REGISTER_CLOCK("mxsdhci.1", NULL, esdhc2_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt", gpt1_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt", gpt2_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt", gpt3_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt", gpt4_clk[0])
+ _REGISTER_CLOCK(NULL, "clko_clk", clko_clk)
+ _REGISTER_CLOCK("pata_fsl", NULL, ata_clk[0])
+ _REGISTER_CLOCK("FlexCAN.0", NULL, can_clk[0])
+ _REGISTER_CLOCK("mxc_esai.0", NULL, esai_clk[0])
+ _REGISTER_CLOCK("mxc_iim.0", NULL, iim_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk[0])
+ _REGISTER_CLOCK(NULL, "scc_clk", scc_clk)
+ _REGISTER_CLOCK("mxc_sim.0", NULL, sim1_clk[0])
+ _REGISTER_CLOCK("mxc_sim.0", NULL, sim2_clk[0])
+ _REGISTER_CLOCK("mxc_ssi.0", NULL, ssi1_clk[0])
+ _REGISTER_CLOCK("mxc_ssi.0", NULL, ssi2_clk[0])
+ _REGISTER_CLOCK("mxc_ipu", "csi_clk", csi_clk[0])
+ _REGISTER_CLOCK(NULL, "lcdc_clk", lcdc_clk[0])
+ _REGISTER_CLOCK(NULL, "slcdc_clk", lcdc_clk[0])
+ _REGISTER_CLOCK(NULL, "rng_clk", rng_clk)
+ _REGISTER_CLOCK(NULL, "audmux_clk", audmux_clk)
+ _REGISTER_CLOCK(NULL, "ect_clk", ect_clk)
+ _REGISTER_CLOCK(NULL, "epit1_clk", epit1_clk[0])
+ _REGISTER_CLOCK(NULL, "epit2_clk", epit2_clk[0])
+ _REGISTER_CLOCK(NULL, "gpio_clk", gpio_clk[0])
+ _REGISTER_CLOCK(NULL, "iomuxc_clk", iomuxc_clk)
+ _REGISTER_CLOCK(NULL, "spba_clk", spba_clk)
+ _REGISTER_CLOCK(NULL, "wdog_clk", wdog_clk)
+ _REGISTER_CLOCK(NULL, "per_csi_clk", per_clk[0])
+ _REGISTER_CLOCK(NULL, "per_epit_clk", per_clk[1])
+ _REGISTER_CLOCK(NULL, "per_esai_clk", per_clk[2])
+ _REGISTER_CLOCK(NULL, "per_esdhc1_clk", per_clk[3])
+ _REGISTER_CLOCK(NULL, "per_esdhc2_clk", per_clk[4])
+ _REGISTER_CLOCK(NULL, "per_gpt_clk", per_clk[5])
+ _REGISTER_CLOCK(NULL, "per_i2c_clk", per_clk[6])
+ _REGISTER_CLOCK(NULL, "per_lcdc_clk", per_clk[7])
+ _REGISTER_CLOCK(NULL, "per_nfc_clk", per_clk[8])
+ _REGISTER_CLOCK(NULL, "per_owire_clk", per_clk[9])
+ _REGISTER_CLOCK(NULL, "per_pwm_clk", per_clk[10])
+ _REGISTER_CLOCK(NULL, "per_sim1_clk", per_clk[11])
+ _REGISTER_CLOCK(NULL, "per_sim2_clk", per_clk[12])
+ _REGISTER_CLOCK(NULL, "per_ssi1_clk", per_clk[13])
+ _REGISTER_CLOCK(NULL, "per_ssi2_clk", per_clk[14])
+ _REGISTER_CLOCK(NULL, "per_uart_clk", per_clk[15])
};
+static struct mxc_clk mxc_clks[ARRAY_SIZE(lookups)];
+
+/*!
+ * Function to get timer clock rate early in boot process before clock tree is
+ * initialized.
+ *
+ * @return Clock rate for timer
+ */
+unsigned long __init clk_early_get_timer_rate(void)
+{
+ upll_clk.get_rate(&upll_clk);
+ per_clk[5].get_rate(&per_clk[5]);
+ per_clk[5].enable(&per_clk[5]);
+
+ return clk_get_rate(&per_clk[5]);
+}
+
int __init mx25_clocks_init(void)
{
+ int i;
+ unsigned long upll_rate;
+ unsigned long ahb_rate;
+
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ mxc_clks[i].reg_clk = lookups[i].clk;
+ if (lookups[i].con_id != NULL)
+ strcpy(mxc_clks[i].name, lookups[i].con_id);
+ else
+ strcpy(mxc_clks[i].name, lookups[i].dev_id);
+ clk_register(&mxc_clks[i]);
+ }
+
/* Turn off all clocks except the ones we need to survive, namely:
* EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
* SCC
*/
__raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
- __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
+
+ __raw_writel((1 << MXC_CCM_CGCR1_GPT1_OFFSET) |
+ (1 << MXC_CCM_CGCR1_IIM_OFFSET),
+ CRM_BASE + CCM_CGCR1);
+
__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
/* Clock source for lcdc is upll */
__raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7), CRM_BASE + 0x64);
- mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+ /* Init all perclk sources to ahb clock*/
+ for (i = 0; i < (sizeof(per_clk) / sizeof(struct clk)); i++)
+ per_clk[i].set_parent(&per_clk[i], &ahb_clk);
+
+ /* GPT clock must be derived from AHB clock */
+ ahb_rate = clk_get_rate(&ahb_clk);
+ clk_set_rate(&per_clk[5], ahb_rate / 10);
+
+ /* LCDC clock must be derived from UPLL clock */
+ upll_rate = clk_get_rate(&upll_clk);
+ clk_set_parent(&per_clk[7], &upll_clk);
+ clk_set_rate(&per_clk[7], upll_rate);
+
+ /* the NFC clock must be derived from AHB clock */
+ clk_set_parent(&per_clk[8], &ahb_clk);
+ clk_set_rate(&per_clk[8], ahb_rate / 6);
+
+ /* sim clock */
+ clk_set_rate(&per_clk[11], ahb_rate / 2);
+
+ /* the csi clock must be derived from UPLL clock */
+ clk_set_parent(&per_clk[0], &upll_clk);
+ clk_set_rate(&per_clk[0], upll_rate / 5);
+
+ pr_info("Clock input source is %ld\n", clk_get_rate(&osc24m_clk));
+
+ clk_enable(&emi_clk);
+ clk_enable(&gpio_clk[0]);
+ clk_enable(&gpio_clk[1]);
+ clk_enable(&gpio_clk[2]);
+ clk_enable(&iim_clk);
+ clk_enable(&gpt1_clk[0]);
+ clk_enable(&iomuxc_clk);
+ clk_enable(&scc_clk);
+
+ mxc_timer_init(&gpt1_clk[0], IO_ADDRESS(MX25_GPT1_BASE_ADDR),
+ MX25_INT_GPT1);
return 0;
}
diff --git a/arch/arm/mach-mx25/cpu.c b/arch/arm/mach-mx25/cpu.c
new file mode 100644
index 000000000000..f64dfbf6cf03
--- /dev/null
+++ b/arch/arm/mach-mx25/cpu.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2010 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-mx25/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX25
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/iram_alloc.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(0x25, CHIP_REV_1_0);
+}
+
+static int __init post_cpu_init(void)
+{
+ void __iomem *base;
+ unsigned int reg;
+
+ iram_init(MX25_IRAM_BASE_ADDR, IRAM_SIZE);
+
+ base = IO_ADDRESS(MX25_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(MX25_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-mx25/crm_regs.h b/arch/arm/mach-mx25/crm_regs.h
new file mode 100644
index 000000000000..b9368dd227a9
--- /dev/null
+++ b/arch/arm/mach-mx25/crm_regs.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX25_CRM_REGS_H__
+
+#include <mach/hardware.h>
+
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(MX25_CRM_BASE_ADDR))
+
+/* Register offsets */
+#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_CCTL (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CGCR0 (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_CGCR1 (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CGCR2 (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_PCDR0 (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_PCDR1 (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_PCDR2 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_PCDR3 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CRDR (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_PMCR2 (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_MCR (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_LPIMR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_LPIMR1 (MXC_CCM_BASE + 0x6C)
+
+#define MXC_CCM_MPCTL_BRMO (1 << 31)
+#define MXC_CCM_MPCTL_PD_OFFSET 26
+#define MXC_CCM_MPCTL_PD_MASK (0xf << 26)
+#define MXC_CCM_MPCTL_MFD_OFFSET 16
+#define MXC_CCM_MPCTL_MFD_MASK (0x3ff << 16)
+#define MXC_CCM_MPCTL_MFI_OFFSET 10
+#define MXC_CCM_MPCTL_MFI_MASK (0xf << 10)
+#define MXC_CCM_MPCTL_MFN_OFFSET 0
+#define MXC_CCM_MPCTL_MFN_MASK 0x3ff
+#define MXC_CCM_MPCTL_LF (1 << 15)
+
+#define MXC_CCM_UPCTL_BRMO (1 << 31)
+#define MXC_CCM_UPCTL_PD_OFFSET 26
+#define MXC_CCM_UPCTL_PD_MASK (0xf << 26)
+#define MXC_CCM_UPCTL_MFD_OFFSET 16
+#define MXC_CCM_UPCTL_MFD_MASK (0x3ff << 16)
+#define MXC_CCM_UPCTL_MFI_OFFSET 10
+#define MXC_CCM_UPCTL_MFI_MASK (0xf << 10)
+#define MXC_CCM_UPCTL_MFN_OFFSET 0
+#define MXC_CCM_UPCTL_MFN_MASK 0x3ff
+#define MXC_CCM_UPCTL_LF (1 << 15)
+
+#define MXC_CCM_CCTL_ARM_OFFSET 30
+#define MXC_CCM_CCTL_ARM_MASK (0x3 << 30)
+#define MXC_CCM_CCTL_AHB_OFFSET 28
+#define MXC_CCM_CCTL_AHB_MASK (0x3 << 28)
+#define MXC_CCM_CCTL_MPLL_RST (1 << 27)
+#define MXC_CCM_CCTL_UPLL_RST (1 << 26)
+#define MXC_CCM_CCTL_LP_CTL_OFFSET 24
+#define MXC_CCM_CCTL_LP_CTL_MASK (0x3 << 24)
+#define MXC_CCM_CCTL_LP_MODE_RUN (0x0 << 24)
+#define MXC_CCM_CCTL_LP_MODE_WAIT (0x1 << 24)
+#define MXC_CCM_CCTL_LP_MODE_DOZE (0x2 << 24)
+#define MXC_CCM_CCTL_LP_MODE_STOP (0x3 << 24)
+#define MXC_CCM_CCTL_UPLL_DISABLE (1 << 23)
+#define MXC_CCM_CCTL_MPLL_BYPASS (1 << 22)
+#define MXC_CCM_CCTL_USB_DIV_OFFSET 16
+#define MXC_CCM_CCTL_USB_DIV_MASK (0x3 << 16)
+#define MXC_CCM_CCTL_CG_CTRL (1 << 15)
+#define MXC_CCM_CCTL_ARM_SRC (1 << 14)
+#define MXC_CCM_CCTL_ARM_SRC_OFFSET 14
+
+#define MXC_CCM_CGCR0_HCLK_ATA_OFFSET 16
+#define MXC_CCM_CGCR0_HCLK_BROM_OFFSET 17
+#define MXC_CCM_CGCR0_HCLK_CSI_OFFSET 18
+#define MXC_CCM_CGCR0_HCLK_EMI_OFFSET 19
+#define MXC_CCM_CGCR0_HCLK_ESAI_OFFSET 20
+#define MXC_CCM_CGCR0_HCLK_ESDHC1_OFFSET 21
+#define MXC_CCM_CGCR0_HCLK_ESDHC2_OFFSET 22
+#define MXC_CCM_CGCR0_HCLK_FEC_OFFSET 23
+#define MXC_CCM_CGCR0_HCLK_LCDC_OFFSET 24
+#define MXC_CCM_CGCR0_HCLK_RTIC_OFFSET 25
+#define MXC_CCM_CGCR0_HCLK_SDMA_OFFSET 26
+#define MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET 27
+#define MXC_CCM_CGCR0_HCLK_USBOTG_OFFSET 28
+
+#define MXC_CCM_CGCR0_PER_CSI_OFFSET 0
+#define MXC_CCM_CGCR0_PER_EPIT_OFFSET 1
+#define MXC_CCM_CGCR0_PER_ESAI_OFFSET 2
+#define MXC_CCM_CGCR0_PER_ESDHC1_OFFSET 3
+#define MXC_CCM_CGCR0_PER_ESDHC2_OFFSET 4
+#define MXC_CCM_CGCR0_PER_GPT_OFFSET 5
+#define MXC_CCM_CGCR0_PER_I2C_OFFSET 6
+#define MXC_CCM_CGCR0_PER_LCDC_OFFSET 7
+#define MXC_CCM_CGCR0_PER_NFC_OFFSET 8
+#define MXC_CCM_CGCR0_PER_OWIRE_OFFSET 9
+#define MXC_CCM_CGCR0_PER_PWM_OFFSET 10
+#define MXC_CCM_CGCR0_PER_SIM1_OFFSET 11
+#define MXC_CCM_CGCR0_PER_SIM2_OFFSET 12
+#define MXC_CCM_CGCR0_PER_SSI1_OFFSET 13
+#define MXC_CCM_CGCR0_PER_SSI2_OFFSET 14
+#define MXC_CCM_CGCR0_PER_UART_OFFSET 15
+
+#define MXC_CCM_CGCR1_AUDMUX_OFFSET 0
+#define MXC_CCM_CGCR1_ATA_OFFSET 1
+#define MXC_CCM_CGCR1_CAN1_OFFSET 2
+#define MXC_CCM_CGCR1_CAN2_OFFSET 3
+#define MXC_CCM_CGCR1_CSI_OFFSET 4
+#define MXC_CCM_CGCR1_CSPI1_OFFSET 5
+#define MXC_CCM_CGCR1_CSPI2_OFFSET 6
+#define MXC_CCM_CGCR1_CSPI3_OFFSET 7
+#define MXC_CCM_CGCR1_DRYICE_OFFSET 8
+#define MXC_CCM_CGCR1_ECT_OFFSET 9
+#define MXC_CCM_CGCR1_EPIT1_OFFSET 10
+#define MXC_CCM_CGCR1_EPIT2_OFFSET 11
+#define MXC_CCM_CGCR1_ESAI_OFFSET 12
+#define MXC_CCM_CGCR1_ESDHC1_OFFSET 13
+#define MXC_CCM_CGCR1_ESDHC2_OFFSET 14
+#define MXC_CCM_CGCR1_FEC_OFFSET 15
+#define MXC_CCM_CGCR1_GPIO1_OFFSET 16
+#define MXC_CCM_CGCR1_GPIO2_OFFSET 17
+#define MXC_CCM_CGCR1_GPIO3_OFFSET 18
+#define MXC_CCM_CGCR1_GPT1_OFFSET 19
+#define MXC_CCM_CGCR1_GPT2_OFFSET 20
+#define MXC_CCM_CGCR1_GPT3_OFFSET 21
+#define MXC_CCM_CGCR1_GPT4_OFFSET 22
+#define MXC_CCM_CGCR1_I2C1_OFFSET 23
+#define MXC_CCM_CGCR1_I2C2_OFFSET 24
+#define MXC_CCM_CGCR1_I2C3_OFFSET 25
+#define MXC_CCM_CGCR1_IIM_OFFSET 26
+#define MXC_CCM_CGCR1_IOMUXC_OFFSET 27
+#define MXC_CCM_CGCR1_KPP_OFFSET 28
+#define MXC_CCM_CGCR1_LCDC_OFFSET 29
+#define MXC_CCM_CGCR1_OWIRE_OFFSET 30
+#define MXC_CCM_CGCR1_PWM1_OFFSET 31
+
+#define MXC_CCM_CGCR2_PWM2_OFFSET (32-32)
+#define MXC_CCM_CGCR2_PWM3_OFFSET (33-32)
+#define MXC_CCM_CGCR2_PWM4_OFFSET (34-32)
+#define MXC_CCM_CGCR2_RNGB_OFFSET (35-32)
+#define MXC_CCM_CGCR2_RTIC_OFFSET (36-32)
+#define MXC_CCM_CGCR2_SCC_OFFSET (37-32)
+#define MXC_CCM_CGCR2_SDMA_OFFSET (38-32)
+#define MXC_CCM_CGCR2_SIM1_OFFSET (39-32)
+#define MXC_CCM_CGCR2_SIM2_OFFSET (40-32)
+#define MXC_CCM_CGCR2_SLCDC_OFFSET (41-32)
+#define MXC_CCM_CGCR2_SPBA_OFFSET (42-32)
+#define MXC_CCM_CGCR2_SSI1_OFFSET (43-32)
+#define MXC_CCM_CGCR2_SSI2_OFFSET (44-32)
+#define MXC_CCM_CGCR2_TCHSCRN_OFFSET (45-32)
+#define MXC_CCM_CGCR2_UART1_OFFSET (46-32)
+#define MXC_CCM_CGCR2_UART2_OFFSET (47-32)
+#define MXC_CCM_CGCR2_UART3_OFFSET (48-32)
+#define MXC_CCM_CGCR2_UART4_OFFSET (49-32)
+#define MXC_CCM_CGCR2_UART5_OFFSET (50-32)
+#define MXC_CCM_CGCR2_WDOG_OFFSET (51-32)
+
+#define MXC_CCM_CGCR0_STOP_MODE_MASK \
+ ((1 << MXC_CCM_CGCR0_HCLK_SLCDC_OFFSET) | \
+ (1 << MXC_CCM_CGCR0_HCLK_RTIC_OFFSET) | \
+ (1 << MXC_CCM_CGCR0_HCLK_EMI_OFFSET) | \
+ (1 << MXC_CCM_CGCR0_HCLK_BROM_OFFSET))
+
+#define MXC_CCM_CGCR1_STOP_MODE_MASK ((1 << MXC_CCM_CGCR1_IIM_OFFSET) | \
+ (1 << MXC_CCM_CGCR1_CAN2_OFFSET) | \
+ (1 << MXC_CCM_CGCR1_CAN1_OFFSET))
+
+#define MXC_CCM_CGCR2_STOP_MODE_MASK ((1 << MXC_CCM_CGCR2_SPBA_OFFSET) | \
+ (1 << MXC_CCM_CGCR2_SDMA_OFFSET) | \
+ (1 << MXC_CCM_CGCR2_RTIC_OFFSET))
+
+#define MXC_CCM_PCDR1_PERDIV1_MASK 0x3f
+
+#define MXC_CCM_RCSR_NF16B (1 << 14)
+
+#define MXC_CCM_PMCR1_CPEN_EMI (1 << 29)
+#define MXC_CCM_PMCR1_CSPAEM_P_OFFSET 26
+#define MXC_CCM_PMCR1_CSPAEM_N_OFFSET 24
+#define MXC_CCM_PMCR1_CSPAEM_MASK (0xf << 24)
+#define MXC_CCM_PMCR1_WBCN_OFFSET 16
+#define MXC_CCM_PMCR1_CPEN (1 << 13)
+#define MXC_CCM_PMCR1_CSPA_P_OFFSET 11
+#define MXC_CCM_PMCR1_CSPA_N_OFFSET 9
+#define MXC_CCM_PMCR1_CSPA_MASK (0xf << 9)
+
+#define MXC_CCM_PMCR1_WBCN_MASK (0xff << 16)
+#define MXC_CCM_PMCR1_WBCN_DEFAULT 0xa0
+#define MXC_CCM_PMCR1_WBB_INCR 0
+#define MXC_CCM_PMCR1_WBB_MODE 1
+#define MXC_CCM_PMCR1_WBB_DECR 2
+#define MXC_CCM_PMCR1_WBB_MINI 3
+
+#define MXC_CCM_PMCR2_VSTBY (1 << 17)
+#define MXC_CCM_PMCR2_OSC24M_DOWN (1 << 16)
+
+#define MXC_CCM_PMCR1_AWB_EN (MXC_CCM_PMCR1_CPEN_EMI | \
+ MXC_CCM_PMCR1_CPEN | \
+ (MXC_CCM_PMCR1_WBCN_DEFAULT << \
+ MXC_CCM_PMCR1_WBCN_OFFSET))
+
+#define MXC_CCM_PMCR1_WBB_DEFAULT ((MXC_CCM_PMCR1_WBB_DECR << \
+ MXC_CCM_PMCR1_CSPAEM_P_OFFSET) | \
+ (MXC_CCM_PMCR1_WBB_DECR << \
+ MXC_CCM_PMCR1_CSPAEM_N_OFFSET) | \
+ (MXC_CCM_PMCR1_WBB_DECR << \
+ MXC_CCM_PMCR1_CSPA_P_OFFSET) | \
+ (MXC_CCM_PMCR1_WBB_DECR << \
+ MXC_CCM_PMCR1_CSPA_N_OFFSET))
+
+#define MXC_CCM_PMCR1_AWB_DEFAULT (MXC_CCM_PMCR1_AWB_EN | \
+ MXC_CCM_PMCR1_WBB_DEFAULT)
+
+#define MXC_CCM_MCR_USB_XTAL_MUX_OFFSET 31
+#define MXC_CCM_MCR_CLKO_EN_OFFSET 30
+#define MXC_CCM_MCR_CLKO_DIV_OFFSET 24
+#define MXC_CCM_MCR_CLKO_DIV_MASK (0x3F << 24)
+#define MXC_CCM_MCR_CLKO_SEL_OFFSET 20
+#define MXC_CCM_MCR_CLKO_SEL_MASK (0xF << 20)
+#define MXC_CCM_MCR_ESAI_CLK_MUX_OFFSET 19
+#define MXC_CCM_MCR_SSI2_CLK_MUX_OFFSET 18
+#define MXC_CCM_MCR_SSI1_CLK_MUX_OFFSET 17
+#define MXC_CCM_MCR_USB_CLK_MUX_OFFSET 16
+
+#define MXC_CCM_MCR_PER_CLK_MUX_MASK (0xFFFF << 0)
+
+#define MXC_CCM_LPIMR0_MASK 0xFFFFFFFF
+#define MXC_CCM_LPIMR1_MASK 0xFFFFFFFF
+
+#endif /* __ARCH_ARM_MACH_MX25_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
index 3a405fa400eb..532ee52c64d5 100644
--- a/arch/arm/mach-mx25/devices.c
+++ b/arch/arm/mach-mx25/devices.c
@@ -1,5 +1,6 @@
/*
* Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,11 +18,103 @@
*/
#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
+#include <linux/fsl_devices.h>
#include <mach/mx25.h>
#include <mach/irqs.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mmc.h>
+#include <mach/sdma.h>
+#include <mach/mxc_iim.h>
+
+#include "iomux.h"
+#include "sdma_script_code.h"
+
+void mxc_sdma_get_script_info(sdma_script_start_addrs *sdma_script_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_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 = -1;
+
+ 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 = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = -1;
+
+ sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = -1;
+
+ 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;
+}
+
+static struct resource sdma_resources[] = {
+ {
+ .start = SDMA_BASE_ADDR,
+ .end = SDMA_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_SDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_dma_device = {
+ .name = "mxc_sdma",
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(sdma_resources),
+ .resource = sdma_resources,
+};
+
+static inline void mxc_init_dma(void)
+{
+ (void)platform_device_register(&mxc_dma_device);
+}
+
static struct resource uart0[] = {
{
.start = 0x43f90000,
@@ -295,25 +388,6 @@ struct platform_device mxc_pwm_device2 = {
.resource = mxc_pwm_resources2,
};
-static struct resource mxc_keypad_resources[] = {
- {
- .start = 0x43fa8000,
- .end = 0x43fabfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 24,
- .end = 24,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_keypad_device = {
- .name = "mxc-keypad",
- .id = -1,
- .num_resources = ARRAY_SIZE(mxc_keypad_resources),
- .resource = mxc_keypad_resources,
-};
-
static struct resource mxc_pwm_resources3[] = {
{
.start = 0x53fc8000,
@@ -515,3 +589,196 @@ struct platform_device mxc_wdt = {
.num_resources = ARRAY_SIZE(mxc_wdt_resources),
.resource = mxc_wdt_resources,
};
+
+/* imx adc driver */
+#if defined(CONFIG_IMX_ADC) || defined(CONFIG_IMX_ADC_MODULE)
+
+static struct resource imx_adc_resources[] = {
+ [0] = {
+ .start = MX25_INT_TSC,
+ .end = MX25_INT_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = MX25_TSC_BASE_ADDR,
+ .end = MX25_TSC_BASE_ADDR + PAGE_SIZE,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device imx_adc_device = {
+ .name = "imx_adc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_adc_resources),
+ .resource = imx_adc_resources,
+ .dev = {
+ .release = NULL,
+ },
+};
+static void imx_init_adc(void)
+{
+ (void)platform_device_register(&imx_adc_device);
+}
+#else
+static void imx_init_adc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_MXC_SOC_ESAI) || defined(CONFIG_SND_MXC_SOC_ESAI_MODULE)
+
+static struct mxc_esai_platform_data esai_data = {
+ .activate_esai_ports = gpio_activate_esai_ports,
+ .deactivate_esai_ports = gpio_deactivate_esai_ports,
+};
+
+static struct resource esai_resources[] = {
+ {
+ .start = MX25_ESAI_BASE_ADDR,
+ .end = MX25_ESAI_BASE_ADDR + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_ESAI,
+ .end = MX25_INT_ESAI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_esai_device = {
+ .name = "mxc_esai",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(esai_resources),
+ .resource = esai_resources,
+ .dev = {
+ .platform_data = &esai_data,
+ },
+};
+
+static void mxc_init_esai(void)
+{
+ platform_device_register(&mxc_esai_device);
+}
+#else
+static void mxc_init_esai(void)
+{
+
+}
+#endif
+
+static struct mxc_audio_platform_data mxc_surround_audio_data = {
+ .ext_ram = 1,
+};
+
+static struct platform_device mxc_alsa_surround_device = {
+ .name = "imx-3stack-wm8580",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_surround_audio_data,
+ },
+};
+
+static void mxc_init_surround_audio(void)
+{
+ platform_device_register(&mxc_alsa_surround_device);
+}
+
+#if defined(CONFIG_MXC_IIM) || defined(CONFIG_MXC_IIM_MODULE)
+static struct resource mxc_iim_resources[] = {
+ {
+ .start = MX25_IIM_BASE_ADDR,
+ .end = MX25_IIM_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mxc_iim_data iim_data = {
+ .bank_start = MXC_IIM_BANK_START_ADDR,
+ .bank_end = MXC_IIM_BANK_END_ADDR,
+};
+
+static struct platform_device mxc_iim_device = {
+ .name = "mxc_iim",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_iim_resources),
+ .resource = mxc_iim_resources,
+ .dev.platform_data = &iim_data,
+};
+
+static inline void mxc_init_iim(void)
+{
+ if (platform_device_register(&mxc_iim_device) < 0)
+ dev_err(&mxc_iim_device.dev,
+ "Unable to register mxc iim device\n");
+}
+#else
+static inline void mxc_init_iim(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_MXC_SOC_SSI) || defined(CONFIG_SND_MXC_SOC_SSI_MODULE)
+
+static struct resource ssi1_resources[] = {
+ {
+ .start = MX25_SSI1_BASE_ADDR,
+ .end = MX25_SSI1_BASE_ADDR + 0x5C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_SSI1,
+ .end = MX25_INT_SSI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_alsa_ssi1_device = {
+ .name = "mxc_ssi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ssi1_resources),
+ .resource = ssi1_resources,
+};
+
+static struct resource ssi2_resources[] = {
+ {
+ .start = MX25_SSI2_BASE_ADDR,
+ .end = MX25_SSI2_BASE_ADDR + 0x5C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_SSI2,
+ .end = MX25_INT_SSI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_alsa_ssi2_device = {
+ .name = "mxc_ssi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(ssi2_resources),
+ .resource = ssi2_resources,
+};
+
+static inline void mxc_init_ssi(void)
+{
+ platform_device_register(&mxc_alsa_ssi1_device);
+ platform_device_register(&mxc_alsa_ssi2_device);
+}
+#else
+static inline void mxc_init_ssi(void)
+{
+}
+#endif /* CONFIG_SND_MXC_SOC_SSI */
+
+static int __init mxc_init_devices(void)
+{
+ mxc_init_dma();
+ mxc_init_surround_audio();
+ imx_init_adc();
+ mxc_init_iim();
+ mxc_init_ssi();
+ mxc_init_esai();
+ return 0;
+}
+
+arch_initcall(mxc_init_devices);
diff --git a/arch/arm/mach-mx25/dma.c b/arch/arm/mach-mx25/dma.c
new file mode 100644
index 000000000000..85a92751a812
--- /dev/null
+++ b/arch/arm/mach-mx25/dma.c
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2008-2010 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_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_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 = MX25_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 = MX25_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 = MX25_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 = MX25_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 = MX25_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 = MX25_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 = MX25_UART4_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .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 = MX25_UART4_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .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 = MX25_UART5_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .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 = MX25_UART5_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .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_ssi1_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX0,
+ .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 = MX25_SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .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_ssi2_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX0,
+ .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 = MX25_SSI2_BASE_ADDR + MXC_SSI_RX1_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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_TX1_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_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_RX1_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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_TX1_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_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_RX1_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_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = MX25_SSI2_BASE_ADDR + MXC_SSI_TX1_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_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_esai_16bit_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ESAI_FIFO_WML,
+ .per_address = MX25_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 = MX25_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 = MX25_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 = MX25_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_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_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_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)
+{
+#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-mx25/iomux.c b/arch/arm/mach-mx25/iomux.c
new file mode 100644
index 000000000000..7c100f2406de
--- /dev/null
+++ b/arch/arm/mach-mx25/iomux.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX25
+ */
+/*!
+ * @file mach-mx25/iomux.c
+ *
+ * @brief I/O Muxing control functions
+ *
+ * @ingroup GPIO_MX25
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include "iomux.h"
+
+/*!
+ * IOMUX register (base) addresses
+ */
+#define IOMUXGPR (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR))
+#define IOMUXSW_MUX_CTL (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x008)
+#define IOMUXSW_MUX_END (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x228)
+#define IOMUXSW_PAD_CTL (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x22C)
+#define IOMUXSW_PAD_END (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x414)
+#define IOMUXSW_INPUT_CTL (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x460)
+#define IOMUXSW_INPUT_END (IO_ADDRESS(MX25_IOMUXC_BASE_ADDR) + 0x580)
+
+#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)
+
+#define PIN_TO_IOMUX_INDEX(pin) (PIN_TO_IOMUX_MUX(pin) >> 2)
+
+static DEFINE_SPINLOCK(gpio_mux_lock);
+static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX];
+#define MUX_USED 0x80
+
+/*!
+ * 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);
+ void *mux_reg = IOMUXGPR + PIN_TO_IOMUX_MUX(pin);
+ u8 *rp;
+
+ BUG_ON(pin_index > MUX_PIN_NUM_MAX);
+ 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 (*rp && *rp != (cfg | MUX_USED)) {
+ /*Console: how to do */
+ printk(KERN_ERR "iomux_config_mux: Warning: iomux pin"
+ " config changed, index=%d register=%p, "
+ " prev=0x%x new=0x%x\n", pin_index, mux_reg,
+ *rp, cfg);
+ ret = -EINVAL;
+ }
+ *rp = cfg | MUX_USED;
+ 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 (IOMUX_TO_GPIO(pin) < MXC_GPIO_IRQS) {
+ if (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_GPIO) ||
+ (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_FUNC) &&
+ ((pin == MX25_PIN_GPIO_A) || (pin == MX25_PIN_GPIO_B) ||
+ (pin == MX25_PIN_GPIO_C) || (pin == MX25_PIN_GPIO_D) ||
+ (pin == MX25_PIN_GPIO_E) || (pin == MX25_PIN_GPIO_F))))
+ ret |= gpio_request(IOMUX_TO_GPIO(pin), NULL);
+ }
+ 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 (IOMUX_TO_GPIO(pin) < MXC_GPIO_IRQS) {
+ if (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_GPIO) ||
+ (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_FUNC) &&
+ ((pin == MX25_PIN_GPIO_A) || (pin == MX25_PIN_GPIO_B) ||
+ (pin == MX25_PIN_GPIO_C) || (pin == MX25_PIN_GPIO_D) ||
+ (pin == MX25_PIN_GPIO_E) || (pin == MX25_PIN_GPIO_F))))
+ gpio_free(IOMUX_TO_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)
+{
+ void *pad_reg = IOMUXGPR + PIN_TO_IOMUX_PAD(pin);
+
+ BUG_ON((pad_reg > IOMUXSW_PAD_END) || (pad_reg < IOMUXSW_PAD_CTL));
+
+ __raw_writel(config, pad_reg);
+}
+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)
+{
+ void *reg = IOMUXSW_INPUT_CTL + (input << 2);
+
+ BUG_ON(input >= MUX_INPUT_NUM_MUX);
+
+ __raw_writel(config, reg);
+}
+EXPORT_SYMBOL(mxc_iomux_set_input);
diff --git a/arch/arm/mach-mx25/iomux.h b/arch/arm/mach-mx25/iomux.h
new file mode 100644
index 000000000000..d91f9764fa8e
--- /dev/null
+++ b/arch/arm/mach-mx25/iomux.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25_IOMUX_H__
+#define __MACH_MX25_IOMUX_H__
+
+#include <linux/types.h>
+#include <mach/gpio.h>
+#include "mx25_pins.h"
+
+/*!
+ * @file mach-mx25/iomux.h
+ *
+ * @brief I/O Muxing control definitions and functions
+ *
+ * @ingroup GPIO_MX25
+ */
+
+typedef unsigned int iomux_pin_name_t;
+
+/*!
+ * IOMUX functions
+ * SW_MUX_CTL
+ */
+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;
+
+/*!
+ * IOMUX pad functions
+ * SW_PAD_CTL
+ */
+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_PULL = 0x1 << 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;
+
+/*!
+ * IOMUX general purpose functions
+ * IOMUXC_GPR1
+ */
+typedef enum iomux_gp_func {
+ MUX_SDCTL_CSD0_SEL = 0x1 << 0,
+ MUX_SDCTL_CSD1_SEL = 0x1 << 1,
+} iomux_gp_func_t;
+
+/*!
+ * IOMUX SELECT_INPUT register index
+ * Base register is IOMUXSW_INPUT_CTL in iomux.c
+ */
+typedef enum iomux_input_select {
+ MUX_IN_AUDMUX_P4_INPUT_DA_AMX = 0,
+ MUX_IN_AUDMUX_P4_INPUT_DB_AMX,
+ MUX_IN_AUDMUX_P4_INPUT_RXCLK_AMX,
+ MUX_IN_AUDMUX_P4_INPUT_RXFS_AMX,
+ MUX_IN_AUDMUX_P4_INPUT_TXCLK_AMX,
+ MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX,
+ MUX_IN_AUDMUX_P7_INPUT_DA_AMX,
+ MUX_IN_AUDMUX_P7_INPUT_TXFS_AMX,
+ MUX_IN_CAN1_IPP_IND_CANRX,
+ MUX_IN_CAN2_IPP_IND_CANRX,
+ MUX_IN_CSI_IPP_CSI_D_0,
+ MUX_IN_CSI_IPP_CSI_D_1,
+ MUX_IN_CSPI1_IPP_IND_SS3_B,
+ MUX_IN_CSPI2_IPP_CSPI_CLK_IN,
+ MUX_IN_CSPI2_IPP_IND_DATAREADY_B,
+ MUX_IN_CSPI2_IPP_IND_MISO,
+ MUX_IN_CSPI2_IPP_IND_MOSI,
+ MUX_IN_CSPI2_IPP_IND_SS0_B,
+ MUX_IN_CSPI2_IPP_IND_SS1_B,
+ MUX_IN_CSPI3_IPP_CSPI_CLK_IN,
+ MUX_IN_CSPI3_IPP_IND_DATAREADY_B,
+ MUX_IN_CSPI3_IPP_IND_MISO,
+ MUX_IN_CSPI3_IPP_IND_MOSI,
+ MUX_IN_CSPI3_IPP_IND_SS0_B,
+ MUX_IN_CSPI3_IPP_IND_SS1_B,
+ MUX_IN_CSPI3_IPP_IND_SS2_B,
+ MUX_IN_CSPI3_IPP_IND_SS3_B,
+ MUX_IN_ESDHC1_IPP_DAT4_IN,
+ MUX_IN_ESDHC1_IPP_DAT5_IN,
+ MUX_IN_ESDHC1_IPP_DAT6_IN,
+ MUX_IN_ESDHC1_IPP_DAT7_IN,
+ MUX_IN_ESDHC2_IPP_CARD_CLK_IN,
+ MUX_IN_ESDHC2_IPP_CMD_IN,
+ MUX_IN_ESDHC2_IPP_DAT0_IN,
+ MUX_IN_ESDHC2_IPP_DAT1_IN,
+ MUX_IN_ESDHC2_IPP_DAT2_IN,
+ MUX_IN_ESDHC2_IPP_DAT3_IN,
+ MUX_IN_ESDHC2_IPP_DAT4_IN,
+ MUX_IN_ESDHC2_IPP_DAT5_IN,
+ MUX_IN_ESDHC2_IPP_DAT6_IN,
+ MUX_IN_ESDHC2_IPP_DAT7_IN,
+ MUX_IN_FEC_FEC_COL,
+ MUX_IN_FEC_FEC_CRS,
+ MUX_IN_FEC_FEC_RDATA_2,
+ MUX_IN_FEC_FEC_RDATA_3,
+ MUX_IN_FEC_FEC_RX_CLK,
+ MUX_IN_FEC_FEC_RX_ER,
+ MUX_IN_I2C2_IPP_SCL_IN,
+ MUX_IN_I2C2_IPP_SDA_IN,
+ MUX_IN_I2C3_IPP_SCL_IN,
+ MUX_IN_I2C3_IPP_SDA_IN,
+ MUX_IN_KPP_IPP_IND_COL_4,
+ MUX_IN_KPP_IPP_IND_COL_5,
+ MUX_IN_KPP_IPP_IND_COL_6,
+ MUX_IN_KPP_IPP_IND_COL_7,
+ MUX_IN_KPP_IPP_IND_ROW_4,
+ MUX_IN_KPP_IPP_IND_ROW_5,
+ MUX_IN_KPP_IPP_IND_ROW_6,
+ MUX_IN_KPP_IPP_IND_ROW_7,
+ MUX_IN_SIM1_PIN_SIM_RCVD1_IN,
+ MUX_IN_SIM1_PIN_SIM_SIMPD1,
+ MUX_IN_SIM1_SIM_RCVD1_IO,
+ MUX_IN_SIM2_PIN_SIM_RCVD1_IN,
+ MUX_IN_SIM2_PIN_SIM_SIMPD1,
+ MUX_IN_SIM2_SIM_RCVD1_IO,
+ MUX_IN_UART3_IPP_UART_RTS_B,
+ MUX_IN_UART3_IPP_UART_RXD_MUX,
+ MUX_IN_UART4_IPP_UART_RTS_B,
+ MUX_IN_UART4_IPP_UART_RXD_MUX,
+ MUX_IN_UART5_IPP_UART_RTS_B,
+ MUX_IN_UART5_IPP_UART_RXD_MUX,
+ MUX_IN_USB_TOP_IPP_IND_OTG_USB_OC,
+ MUX_IN_USB_TOP_IPP_IND_UH2_USB_OC,
+} iomux_input_select_t;
+
+/*!
+ * IOMUX input functions
+ * SW_SELECT_INPUT bits 2-0
+ */
+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;
+
+struct mxc_iomux_pin_cfg {
+ iomux_pin_name_t pin;
+ u8 mux_mode;
+ u16 pad_cfg;
+ u8 in_select;
+ u8 in_mode;
+};
+
+/*!
+ * 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-mx25/mm.c b/arch/arm/mach-mx25/mm.c
index a7e587ff3e9e..2b707da33596 100644
--- a/arch/arm/mach-mx25/mm.c
+++ b/arch/arm/mach-mx25/mm.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999,2000 Arm Limited
* 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 (C) 2005-2007, 2010 Freescale Semiconductor, Inc.
* - add MX31 specific definitions
*
* This program is free software; you can redistribute it and/or modify
diff --git a/arch/arm/mach-mx25/mx25_3stack.c b/arch/arm/mach-mx25/mx25_3stack.c
new file mode 100644
index 000000000000..dc528dd5d130
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25_3stack.c
@@ -0,0 +1,848 @@
+/*
+ * Copyright (C) 2008-2010 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/smsc911x.h>
+#include <linux/fec.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/common.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/keypad.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/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+
+#include "board-mx25_3stack.h"
+#include "crm_regs.h"
+#include "iomux.h"
+#include "devices.h"
+
+/*!
+ * @file mach-mx25/mx25_3stack.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX25
+ */
+
+unsigned int mx25_3stack_board_io;
+
+/* working point(wp): 0 - 399MHz; 1 - 266MHz; 2 - 133MHz; */
+/* 24MHz input clock table */
+static struct cpu_wp cpu_wp_mx25[] = {
+ {
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .cpu_podf = 0x0,
+ .cpu_voltage = 1450000},
+ {
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .cpu_podf = 0x1,
+ .cpu_voltage = 1340000},
+ {
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .cpu_podf = 0x3,
+ .cpu_voltage = 1340000},
+};
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ *wp = 3;
+ return cpu_wp_mx25;
+}
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE)
+static u16 keymapping[16] = {
+ KEY_UP, KEY_DOWN, KEY_VOLUMEDOWN, KEY_HOME,
+ KEY_RIGHT, KEY_LEFT, KEY_ENTER, KEY_VOLUMEUP,
+ KEY_F6, KEY_F8, KEY_F9, KEY_F10,
+ KEY_F1, KEY_F2, KEY_F3, KEY_POWER,
+};
+
+static struct resource mxc_kpp_resources[] = {
+ [0] = {
+ .start = MX25_INT_KPP,
+ .end = MX25_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = MX25_KPP_BASE_ADDR,
+ .end = MX25_KPP_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct keypad_data keypad_plat_data = {
+ .rowmax = 4,
+ .colmax = 4,
+ .learning = 0,
+ .delay = 2,
+ .matrix = keymapping,
+};
+
+/* mxc keypad driver */
+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_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "nand.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 = 256 * 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 resource mxc_nand_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .name = "NFC_AXI_BASE",
+ .start = MX25_NFC_BASE_ADDR,
+ .end = MX25_NFC_BASE_ADDR + SZ_8K - 1,
+ },
+ {
+ .flags = IORESOURCE_IRQ,
+ .start = MX25_INT_NANDFC,
+ .end = MX25_INT_NANDFC,
+ },
+};
+
+
+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,
+ },
+ .resource = mxc_nand_resources,
+ .num_resources = ARRAY_SIZE(mxc_nand_resources),
+};
+
+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_FB_MXC_SYNC_PANEL) || \
+ defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static const char fb_default_mode[] = "CPT-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,
+ },
+};
+
+/*
+ * Power on/off CPT VGA panel.
+ */
+void board_power_lcd(int on)
+{
+ if (on) {
+ /* Enable HSYNC bit of touch screen */
+ imx_adc_set_hsync(1);
+ mx2fb_set_brightness(MXC_DEFAULT_INTENSITY);
+ } else {
+ /* disable HSYNC bit of touchscreen */
+ imx_adc_set_hsync(0);
+ mx2fb_set_brightness(MXC_INTENSITY_OFF);
+ }
+}
+EXPORT_SYMBOL_GPL(board_power_lcd);
+
+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_LCDC) || \
+ defined(CONFIG_BACKLIGHT_MXC_LCDC_MODULE)
+ {
+ .name = "mxc_lcdc_bl",
+ .id = 0,
+ },
+#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
+
+/*!
+ * Power Key interrupt handler.
+ */
+static irqreturn_t power_key_int(int irq, void *dev_id)
+{
+ pr_info("on-off key pressed\n");
+ return 0;
+}
+
+/*!
+ * Power Key initialization.
+ */
+static int __init mxc_init_power_key(void)
+{
+ /*Set power key as wakeup resource */
+ int irq, ret;
+
+ mxc_request_iomux(MX25_PIN_A25, MUX_CONFIG_ALT5);
+ mxc_iomux_set_pad(MX25_PIN_A25, PAD_CTL_DRV_NORMAL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A25), NULL);
+ gpio_direction_input(IOMUX_TO_GPIO(MX25_PIN_A25));
+
+ irq = IOMUX_TO_IRQ(MX25_PIN_A25);
+ 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;
+}
+
+late_initcall(mxc_init_power_key);
+
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "cpld_spi",
+ .max_speed_hz = 18000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+ {
+ .modalias = "wm8580_spi",
+ .max_speed_hz = 8000000, /* max spi SCK clock speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ },
+};
+
+static struct mxc_camera_platform_data camera_data = {
+ .core_regulator = NULL,
+ .io_regulator = NULL,
+ .analog_regulator = NULL,
+ .gpo_regulator = NULL,
+ .mclk = 24000000,
+};
+
+static struct i2c_board_info mxc_i2c_board_info[] __initdata = {
+ {
+ .type = "sgtl5000-i2c",
+ .addr = 0x0a,
+ },
+ {
+ .type = "ak5702-i2c",
+ .addr = 0x13,
+ },
+ {
+ .type = "ov2640",
+ .addr = 0x30,
+ .platform_data = (void *)&camera_data,
+ },
+};
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
+static struct mxc_audio_platform_data sgtl5000_data = {
+ .ssi_num = 2,
+ .src_port = 1,
+ .ext_port = 4,
+ .hp_irq = IOMUX_TO_IRQ(MX25_PIN_A10),
+ .hp_status = headphone_det_status,
+ .sysclk = 8300000,
+};
+
+static struct platform_device mxc_sgtl5000_device = {
+ .name = "imx-3stack-sgtl5000",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &sgtl5000_data,
+ },
+};
+
+static void mxc_init_sgtl5000(void)
+{
+ struct clk *cko1, *parent;
+ unsigned long rate;
+
+ /* cko1 clock */
+ mxc_request_iomux(MX25_PIN_CLKO, MUX_CONFIG_FUNC);
+
+ cko1 = clk_get(NULL, "clko_clk");
+ if (IS_ERR(cko1))
+ return;
+ parent = clk_get(NULL, "ipg_clk");
+ if (IS_ERR(parent))
+ return;
+ clk_set_parent(cko1, parent);
+ rate = clk_round_rate(cko1, 13000000);
+ if (rate < 8000000 || rate > 27000000) {
+ pr_err("Error: SGTL5000 mclk freq %ld out of range!\n", rate);
+ clk_put(parent);
+ clk_put(cko1);
+ return;
+ }
+ clk_set_rate(cko1, rate);
+ clk_enable(cko1);
+ sgtl5000_data.sysclk = rate;
+ sgtl5000_enable_amp();
+ platform_device_register(&mxc_sgtl5000_device);
+}
+#else
+static inline void mxc_init_sgtl5000(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_AK5702) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_AK5702_MODULE)
+static struct platform_device mxc_ak5702_device = {
+ .name = "imx-3stack-ak5702",
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static void mxc_init_ak5702(void)
+{
+ platform_device_register(&mxc_ak5702_device);
+}
+#else
+static inline void mxc_init_ak5702(void)
+{
+}
+#endif
+
+#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_BOARD_IRQ_START,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .flags = 0x8000 | SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &smsc911x_config,
+ },
+ .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_FEC) || defined(CONFIG_FEC_MODULE)
+static struct resource mxc_fec_resources[] = {
+ {
+ .start = MX25_FEC_BASE_ADDR,
+ .end = MX25_FEC_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = MX25_INT_FEC,
+ .end = MX25_INT_FEC,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+static struct fec_platform_data fec_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+struct platform_device mxc_fec_device = {
+ .name = "fec",
+ .id = 0,
+ .dev = {
+ .platform_data = &fec_data,
+ },
+ .num_resources = ARRAY_SIZE(mxc_fec_resources),
+ .resource = mxc_fec_resources,
+};
+
+static __init int mxc_init_fec(void)
+{
+ return platform_device_register(&mxc_fec_device);
+}
+#else
+static inline int mxc_init_fec(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_IMX_SIM) || defined(CONFIG_IMX_SIM_MODULE)
+/* Used to configure the SIM bus */
+static struct mxc_sim_platform_data sim1_data = {
+ .clk_rate = 5000000,
+ .clock_sim = "sim1_clk",
+ .power_sim = NULL,
+ .init = NULL,
+ .exit = NULL,
+ .detect = 1,
+};
+
+/*!
+ * Resource definition for the SIM
+ */
+static struct resource mxc_sim1_resources[] = {
+ [0] = {
+ .start = MX25_SIM1_BASE_ADDR,
+ .end = MX25_SIM1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MX25_INT_SIM1,
+ .end = MX25_INT_SIM1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for IMX SIM */
+static struct platform_device mxc_sim1_device = {
+ .name = "mxc_sim",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &sim1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxc_sim1_resources),
+ .resource = mxc_sim1_resources,
+};
+
+static inline void mxc_init_sim(void)
+{
+ (void)platform_device_register(&mxc_sim1_device);
+}
+#else
+static inline void mxc_init_sim(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE)
+static struct mxc_mmc_platform_data mmc1_data = {
+ .ocr_mask = MMC_VDD_29_30 | MMC_VDD_32_33,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 400000,
+ .max_clk = 52000000,
+ .card_inserted_state = 1,
+ .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 = MX25_MMC_SDHC1_BASE_ADDR,
+ .end = MX25_MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MX25_INT_SDHC1,
+ .end = MX25_INT_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IOMUX_TO_IRQ(MX25_PIN_A15),
+ .end = IOMUX_TO_IRQ(MX25_PIN_A15),
+ .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 = &mmc1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+#ifdef CONFIG_MMC_IMX_ESDHCI_SELECT2
+static struct mxc_mmc_platform_data mmc2_data = {
+ .ocr_mask = MMC_VDD_29_30 | MMC_VDD_32_33,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 400000,
+ .max_clk = 52000000,
+ .card_fixed = 1,
+ .card_inserted_state = 1,
+ .status = sdhc_get_card_det_status,
+ .clock_mmc = "esdhc2_clk",
+};
+
+/*!
+ * Resource definition for the SDHC2
+ */
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MX25_MMC_SDHC2_BASE_ADDR,
+ .end = MX25_MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MX25_INT_SDHC2,
+ .end = MX25_INT_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC2 */
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxsdhci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+#endif
+
+static inline void mxc_init_mmc(void)
+{
+ (void)platform_device_register(&mxcsdhc1_device);
+#ifdef CONFIG_MMC_IMX_ESDHCI_SELECT2
+ (void)platform_device_register(&mxcsdhc2_device);
+#endif
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+static void __init mx25_3stack_timer_init(void)
+{
+ struct clk *uart_clk;
+
+ mx25_clocks_init();
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(MX25_UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx25_3stack_timer_init,
+};
+
+#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
+static void flexcan_xcvr_enable(int id, int en)
+{
+ static int pwdn;
+
+ if (id != 1) /* MX25 3-stack uses only CAN2 */
+ return;
+
+ if (en) {
+ if (!pwdn++)
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D14), 0);
+ } else {
+ if (!--pwdn)
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D14), 1);
+ }
+}
+
+struct flexcan_platform_data flexcan_data[] = {
+ {
+ .core_reg = NULL,
+ .io_reg = NULL,
+ .xcvr_enable = flexcan_xcvr_enable,
+ .active = gpio_can_active,
+ .inactive = gpio_can_inactive,
+ .br_clksrc = 1,
+ .br_rjw = 2,
+ .br_presdiv = 6,
+ .br_propseg = 4,
+ .br_pseg1 = 4,
+ .br_pseg2 = 7,
+ .bcc = 1,
+ .srx_dis = 1,
+ .smp = 1,
+ .boff_rec = 1,
+ .ext_msg = 1,
+ .std_msg = 1,},
+ {
+ .core_reg = NULL,
+ .io_reg = NULL,
+ .xcvr_enable = flexcan_xcvr_enable,
+ .active = gpio_can_active,
+ .inactive = gpio_can_inactive,
+ .br_clksrc = 1,
+ .br_rjw = 2,
+ .br_presdiv = 6,
+ .br_propseg = 4,
+ .br_pseg1 = 4,
+ .br_pseg2 = 7,
+ .bcc = 1,
+ .srx_dis = 1,
+ .smp = 1,
+ .boff_rec = 1,
+ .ext_msg = 1,
+ .std_msg = 1,},
+};
+
+static struct resource flexcan1_resources[] = {
+ {
+ .start = MX25_CAN1_BASE_ADDR,
+ .end = MX25_CAN1_BASE_ADDR + 0x97F,
+ .flags = IORESOURCE_MEM,},
+ {
+ .start = MX25_INT_CAN1,
+ .end = MX25_INT_CAN1,
+ .flags = IORESOURCE_IRQ,}
+};
+static struct resource flexcan2_resources[] = {
+ {
+ .start = MX25_CAN3_BASE_ADDR,
+ .end = MX25_CAN3_BASE_ADDR + 0x97F,
+ .flags = IORESOURCE_MEM,},
+ {
+ .start = MX25_INT_CAN2,
+ .end = MX25_INT_CAN2,
+ .flags = IORESOURCE_IRQ,}
+};
+
+static struct platform_device flexcan_devices[] = {
+ {
+ .name = "FlexCAN",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(flexcan1_resources),
+ .resource = flexcan1_resources,},
+ {
+ .name = "FlexCAN",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(flexcan2_resources),
+ .resource = flexcan2_resources,},
+};
+
+static inline void mxc_init_flexcan(void)
+{
+#ifdef CONFIG_FLEXCAN_MXC_SELECT1
+ /* MX25 3stack doesn't use CAN1 */
+ mxc_register_device(&flexcan_devices[0], &flexcan_data[0]);
+#endif
+ mxc_register_device(&flexcan_devices[1], &flexcan_data[1]);
+}
+#else
+static inline void mxc_init_flexcan(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
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ pr_info("AIPS1 VA base: 0x%p\n", IO_ADDRESS(MX25_AIPS1_BASE_ADDR));
+ mxc_cpu_common_init();
+ mx25_3stack_gpio_init();
+ mxc_init_keypad();
+#ifdef CONFIG_I2C
+ i2c_register_board_info(0, mxc_i2c_board_info,
+ ARRAY_SIZE(mxc_i2c_board_info));
+#endif
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+ mx25_3stack_init_mc34704();
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_nand_mtd();
+ mxc_init_sgtl5000();
+ mxc_init_ak5702();
+ mxc_init_mmc();
+ mxc_init_sim();
+ mxc_init_fec();
+ mxc_init_flexcan();
+ mxc_register_device(&mx25_rtc_device, NULL);
+}
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX25_3DS data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX25_3DS, "Freescale MX25 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = MX25_AIPS1_BASE_ADDR,
+ .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx25_map_io,
+ .init_irq = mx25_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx25/mx25_3stack_cpld.c b/arch/arm/mach-mx25/mx25_3stack_cpld.c
new file mode 100644
index 000000000000..32fb68ae68c0
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25_3stack_cpld.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2008-2010 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-mx25_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx25/mx25_3stack_cpld.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX25
+ */
+
+extern int mxc_spi_poll_transfer(struct spi_device *spi,
+ struct spi_transfer *t);
+static int __init mxc_expio_init(void);
+
+struct spi_device *cpld_spi;
+
+/*!
+ * This function is used to tranfer data to CPLD regs over CSPI
+ */
+static inline int mx25_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,
+ };
+
+ if (!cpld_spi)
+ return -1;
+
+ 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);
+ mx25_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);
+ mx25_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);
+ mx25_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);
+
+ mx25_3ds_cpld_rw((u8 *) frame, 2);
+
+ return 0;
+}
+EXPORT_SYMBOL(spi_cpld_write);
+
+static int __init mx25_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);
+
+ mxc_expio_init();
+ return 0;
+}
+
+/*!
+ * This structure contains pointers to the CPLD callback functions.
+ */
+static struct spi_driver mx25_3ds_cpld_driver = {
+ .driver = {
+ .name = "cpld_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = mx25_3ds_cpld_probe,
+};
+
+static int __init mx25_3ds_cpld_init(void)
+{
+ pr_info("Registering the CPLD Driver\n");
+ return spi_register_driver(&mx25_3ds_cpld_driver);
+}
+device_initcall(mx25_3ds_cpld_init);
+
+static int __initdata is_dbg_removed = { 0 };
+static int __init remove_dbg_setup(char *__unused)
+{
+ is_dbg_removed = 1;
+ return 0;
+}
+__setup("remove_dbg", remove_dbg_setup);
+
+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_BOARD_IRQ_START;
+
+ 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;
+
+ if (is_dbg_removed)
+ return 0;
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_request_iomux(MX25_PIN_PWM, MUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX25_PIN_PWM, PAD_CTL_PUE_PUD);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_PWM), NULL);
+ gpio_direction_input(IOMUX_TO_GPIO(MX25_PIN_PWM));
+
+ for (i = MXC_BOARD_IRQ_START;
+ i < (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS);
+ 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(MX25_PIN_PWM), IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(IOMUX_TO_IRQ(MX25_PIN_PWM),
+ mxc_expio_irq_handler);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-mx25/mx25_3stack_gpio.c b/arch/arm/mach-mx25/mx25_3stack_gpio.c
new file mode 100644
index 000000000000..042aca30e9a7
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25_3stack_gpio.c
@@ -0,0 +1,1367 @@
+/*
+ * Copyright (C) 2008-2010 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-mx25_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx25/mx25_3stack_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX25
+ */
+static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = {
+};
+
+static struct mxc_iomux_pin_cfg __initdata sim_iomux_pins[] = {
+ /* SIM1 */
+ /* SIM1 CLK */
+ {
+ MX25_PIN_CSI_D2, MUX_CONFIG_ALT4,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_CMOS | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM1 RST */
+ {
+ MX25_PIN_CSI_D3, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_HIGH | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_CMOS | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM1 VEN */
+ {
+ MX25_PIN_CSI_D4, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_HIGH | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_CMOS | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM1 TX */
+ {
+ MX25_PIN_CSI_D5, MUX_CONFIG_ALT4,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_CMOS | PAD_CTL_22K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_OpenDrain | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM1 PD */
+ {
+ MX25_PIN_CSI_D6, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_HIGH | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_CMOS | PAD_CTL_22K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM2 */
+ /* SIM2 CLK */
+ {
+ MX25_PIN_CSI_D8, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_NORMAL | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM2 RST */
+ {
+ MX25_PIN_CSI_D9, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_NORMAL | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM2 VEN */
+ {
+ MX25_PIN_CSI_MCLK, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_NORMAL | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PULL | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_NONE,
+ },
+ /* SIM2 TX */
+ {
+ MX25_PIN_CSI_VSYNC, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_NORMAL | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+ /* SIM2 PD */
+ {
+ MX25_PIN_CSI_HSYNC, MUX_CONFIG_ALT4,
+ PAD_CTL_DRV_NORMAL | PAD_CTL_DRV_3_3V |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE,
+ },
+};
+
+static int __initdata enable_sim = { 0 };
+static int __init sim_setup(char *__unused)
+{
+ enable_sim = 1;
+ return 1;
+}
+
+__setup("sim", sim_setup);
+
+/*!
+ * This system-wide 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_mx25_3stack() during system startup. This function is board
+ * specific.
+ */
+void __init mx25_3stack_gpio_init(void)
+{
+ int i, num = 0;
+ struct mxc_iomux_pin_cfg *pin_ptr;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_iomux_pins); i++) {
+ mxc_request_iomux(mxc_iomux_pins[i].pin,
+ mxc_iomux_pins[i].mux_mode);
+ if (mxc_iomux_pins[i].pad_cfg)
+ mxc_iomux_set_pad(mxc_iomux_pins[i].pin,
+ mxc_iomux_pins[i].pad_cfg);
+ if (mxc_iomux_pins[i].in_select)
+ mxc_iomux_set_input(mxc_iomux_pins[i].in_select,
+ mxc_iomux_pins[i].in_mode);
+ }
+
+ if (enable_sim) {
+ pin_ptr = sim_iomux_pins;
+ num = ARRAY_SIZE(sim_iomux_pins);
+ }
+
+ for (i = 0; i < num; i++) {
+ mxc_request_iomux(pin_ptr[i].pin, pin_ptr[i].mux_mode);
+ if (pin_ptr[i].pad_cfg)
+ mxc_iomux_set_pad(pin_ptr[i].pin, pin_ptr[i].pad_cfg);
+ if (pin_ptr[i].in_select)
+ mxc_iomux_set_input(pin_ptr[i].in_select,
+ pin_ptr[i].in_mode);
+ }
+}
+
+/*!
+ * Activate a UART port
+ *
+ * @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) {
+ case 0:
+ /* UART 1 IOMUX Configs */
+ mxc_request_iomux(MX25_PIN_UART1_RXD, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART1_TXD, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART1_RTS, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART1_CTS, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX25_PIN_UART1_RXD,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX25_PIN_UART1_TXD,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX25_PIN_UART1_RTS,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX25_PIN_UART1_CTS,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+
+ break;
+ case 1:
+ /* UART 2 IOMUX Configs */
+ mxc_request_iomux(MX25_PIN_UART2_RXD, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART2_TXD, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART2_RTS, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_UART2_CTS, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX25_PIN_UART2_RXD,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX25_PIN_UART2_TXD, PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX25_PIN_UART2_RTS,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX25_PIN_UART2_CTS, PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ break;
+ case 2:
+ /* UART 3 IOMUX Configs */
+ mxc_request_iomux(MX25_PIN_KPP_ROW0, MUX_CONFIG_ALT1); /*RXD*/
+ mxc_request_iomux(MX25_PIN_KPP_ROW1, MUX_CONFIG_ALT1); /*TXD*/
+ mxc_request_iomux(MX25_PIN_KPP_ROW2, MUX_CONFIG_ALT1); /*RTS*/
+ mxc_request_iomux(MX25_PIN_KPP_ROW3, MUX_CONFIG_ALT1); /*CTS*/
+
+ mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RTS_B,
+ INPUT_CTL_PATH1);
+ mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RXD_MUX,
+ INPUT_CTL_PATH1);
+ break;
+ case 3:
+ /* UART 4 IOMUX Configs */
+ mxc_request_iomux(MX25_PIN_LD8, MUX_CONFIG_ALT2); /*RXD*/
+ mxc_request_iomux(MX25_PIN_LD9, MUX_CONFIG_ALT2); /*TXD*/
+ mxc_request_iomux(MX25_PIN_LD10, MUX_CONFIG_ALT2); /*RTS*/
+ mxc_request_iomux(MX25_PIN_LD11, MUX_CONFIG_ALT2); /*CTS*/
+
+ mxc_iomux_set_input(MUX_IN_UART4_IPP_UART_RTS_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_UART4_IPP_UART_RXD_MUX,
+ INPUT_CTL_PATH0);
+ case 4:
+ /* UART 5 IOMUX Configs */
+ mxc_request_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_ALT1); /*RXD*/
+ mxc_request_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_ALT1); /*TXD*/
+ mxc_request_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_ALT1); /*RTS*/
+ mxc_request_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_ALT1); /*CTS*/
+
+ mxc_iomux_set_input(MUX_IN_UART5_IPP_UART_RTS_B,
+ INPUT_CTL_PATH1);
+ mxc_iomux_set_input(MUX_IN_UART5_IPP_UART_RXD_MUX,
+ INPUT_CTL_PATH1);
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_uart_active);
+
+/*!
+ * Inactivate a UART port
+ *
+ * @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:
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART1_RXD), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART1_TXD), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART1_RTS), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART1_CTS), NULL);
+
+ mxc_free_iomux(MX25_PIN_UART1_RXD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART1_TXD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART1_RTS, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART1_CTS, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART2_RXD), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART2_TXD), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART2_RTS), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART2_CTS), NULL);
+
+ mxc_free_iomux(MX25_PIN_UART2_RXD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART2_TXD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART2_RTS, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART2_CTS, MUX_CONFIG_GPIO);
+ break;
+ case 2:
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW3), NULL);
+
+ mxc_free_iomux(MX25_PIN_KPP_ROW0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW3, MUX_CONFIG_GPIO);
+ break;
+ case 3:
+ mxc_free_iomux(MX25_PIN_LD8, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD9, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD10, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD11, MUX_CONFIG_FUNC);
+ break;
+ case 4:
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D3), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D4), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D5), NULL);
+
+ mxc_free_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D5, MUX_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);
+
+/*!
+ * Activate Keypad
+ */
+void gpio_keypad_active(void)
+{
+ mxc_request_iomux(MX25_PIN_KPP_ROW0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_ROW1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_ROW2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_ROW3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_COL0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_COL1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_COL2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_KPP_COL3, MUX_CONFIG_FUNC);
+
+#define KPP_PAD_CTL_ROW (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | \
+ PAD_CTL_100K_PU)
+#define KPP_PAD_CTL_COL (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | \
+ PAD_CTL_100K_PU | PAD_CTL_ODE_OpenDrain)
+
+ mxc_iomux_set_pad(MX25_PIN_KPP_ROW0, KPP_PAD_CTL_ROW);
+ mxc_iomux_set_pad(MX25_PIN_KPP_ROW1, KPP_PAD_CTL_ROW);
+ mxc_iomux_set_pad(MX25_PIN_KPP_ROW2, KPP_PAD_CTL_ROW);
+ mxc_iomux_set_pad(MX25_PIN_KPP_ROW3, KPP_PAD_CTL_ROW);
+ mxc_iomux_set_pad(MX25_PIN_KPP_COL0, KPP_PAD_CTL_COL);
+ mxc_iomux_set_pad(MX25_PIN_KPP_COL1, KPP_PAD_CTL_COL);
+ mxc_iomux_set_pad(MX25_PIN_KPP_COL2, KPP_PAD_CTL_COL);
+ mxc_iomux_set_pad(MX25_PIN_KPP_COL3, KPP_PAD_CTL_COL);
+
+#undef KPP_PAD_CTL_ROW
+#undef KPP_PAD_CTL_COL
+}
+EXPORT_SYMBOL(gpio_keypad_active);
+
+/*!
+ * Inactivate Keypad
+ */
+void gpio_keypad_inactive(void)
+{
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_ROW3), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_COL0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_COL1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_COL2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_KPP_COL3), NULL);
+
+ mxc_free_iomux(MX25_PIN_KPP_ROW0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_ROW3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_COL0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_COL1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_COL2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_KPP_COL3, MUX_CONFIG_GPIO);
+}
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+/*!
+ * Activate FEC
+ */
+void gpio_fec_active(void)
+{
+ mxc_request_iomux(MX25_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_MDC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_POWER_FAIL, MUX_CONFIG_FUNC); /* PHY INT */
+
+#define FEC_PAD_CTL1 (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PUE_PUD | \
+ PAD_CTL_PKE_ENABLE)
+#define FEC_PAD_CTL2 (PAD_CTL_PUE_PUD)
+
+ mxc_iomux_set_pad(MX25_PIN_FEC_TX_CLK, FEC_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_FEC_RX_DV, FEC_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_FEC_RDATA0, FEC_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_FEC_TDATA0, FEC_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_FEC_TX_EN, FEC_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_FEC_MDC, FEC_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_FEC_MDIO, FEC_PAD_CTL1 | PAD_CTL_22K_PU);
+ mxc_iomux_set_pad(MX25_PIN_FEC_RDATA1, FEC_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_FEC_TDATA1, FEC_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_POWER_FAIL, FEC_PAD_CTL1);
+
+ /*
+ * Set up the FEC_RESET_B and FEC_ENABLE GPIO pins.
+ * Assert FEC_RESET_B, then power up the PHY by asserting
+ * FEC_ENABLE, at the same time lifting FEC_RESET_B.
+ *
+ * FEC_RESET_B: gpio2[3] is ALT 5 mode of pin D12
+ * FEC_ENABLE_B: gpio4[8] is ALT 5 mode of pin A17
+ */
+ mxc_request_iomux(MX25_PIN_A17, MUX_CONFIG_ALT5); /* FEC_EN */
+ mxc_request_iomux(MX25_PIN_D12, MUX_CONFIG_ALT5); /* FEC_RESET_B */
+
+ mxc_iomux_set_pad(MX25_PIN_A17, PAD_CTL_ODE_OpenDrain);
+ mxc_iomux_set_pad(MX25_PIN_D12, 0);
+
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A17), "a17");
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_D12), "d12");
+
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_A17), 0); /* FEC_EN */
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_D12), 0); /* FEC_RESET_B */
+
+ /* drop PHY power */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A17), 0); /* FEC_EN */
+
+ /* assert reset */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D12), 0); /* FEC_RESET_B */
+ udelay(2); /* spec says 1us min */
+
+ /* turn on PHY power and lift reset */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A17), 1); /* FEC_EN */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D12), 1); /* FEC_RESET_B */
+
+#undef FEC_PAD_CTL_COMMON
+#undef FEC_PAD_CTL1
+#undef FEC_PAD_CTL2
+}
+EXPORT_SYMBOL(gpio_fec_active);
+
+/*!
+ * Inactivate FEC
+ */
+void gpio_fec_inactive(void)
+{
+ /*
+ * Turn off the PHY.
+ */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A17), 0);
+
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_TX_CLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_RX_DV), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_RDATA0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_TDATA0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_TX_EN), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_MDC), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_MDIO), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_RDATA1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_TDATA1), NULL);
+
+ mxc_free_iomux(MX25_PIN_FEC_TX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_RDATA0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_TDATA0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_TX_EN, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_MDC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_MDIO, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_TDATA1, MUX_CONFIG_GPIO);
+ mxc_request_iomux(MX25_PIN_POWER_FAIL, MUX_CONFIG_FUNC); /* PHY INT */
+
+ mxc_free_iomux(MX25_PIN_A17, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_D12, MUX_CONFIG_GPIO); /* FEC_RESET_B */
+
+ /* We keep pin A17, so FEC_ENABLE doesn't float */
+}
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+/*!
+ * Activate an I2C device
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+#define I2C_PAD_CTL (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU | PAD_CTL_ODE_OpenDrain)
+
+ switch (i2c_num) {
+ case 0:
+ /*I2C1*/
+ mxc_request_iomux(MX25_PIN_I2C1_CLK, MUX_CONFIG_SION);
+ mxc_request_iomux(MX25_PIN_I2C1_DAT, MUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX25_PIN_I2C1_CLK, I2C_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_I2C1_DAT, I2C_PAD_CTL);
+ break;
+ case 1:
+ /*I2C2*/
+ mxc_request_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_ALT2); /*SCL*/
+ mxc_request_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_ALT2); /*SDA*/
+ mxc_iomux_set_pad(MX25_PIN_GPIO_C, I2C_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_D, I2C_PAD_CTL);
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SCL_IN, INPUT_CTL_PATH1);
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SDA_IN, INPUT_CTL_PATH1);
+
+#if 0
+ /* Or use FEC pins if it is not used */
+ mxc_request_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_ALT1); /*SCL*/
+ mxc_request_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_ALT1); /*SDA*/
+ mxc_iomux_set_pad(MX25_PIN_FEC_RDATA1, I2C_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_FEC_RX_DV, I2C_PAD_CTL);
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SCL_IN, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SDA_IN, INPUT_CTL_PATH0);
+#endif
+
+ break;
+ case 2:
+ /*I2C3*/
+ mxc_request_iomux(MX25_PIN_HSYNC, MUX_CONFIG_ALT2); /*SCL*/
+ mxc_request_iomux(MX25_PIN_VSYNC, MUX_CONFIG_ALT2); /*SDA*/
+ mxc_iomux_set_pad(MX25_PIN_HSYNC, I2C_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_VSYNC, I2C_PAD_CTL);
+ mxc_iomux_set_input(MUX_IN_I2C3_IPP_SCL_IN, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_I2C3_IPP_SDA_IN, INPUT_CTL_PATH0);
+ break;
+ default:
+ break;
+ }
+#undef I2C_PAD_CTL
+}
+EXPORT_SYMBOL(gpio_i2c_active);
+
+/*!
+ * Inactivate an I2C device
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ /*I2C1*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_I2C1_CLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_I2C1_DAT), NULL);
+ mxc_free_iomux(MX25_PIN_I2C1_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_I2C1_DAT, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ /*I2C2*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_C), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_D), NULL);
+ mxc_free_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_GPIO);
+
+#if 0
+ /* Or use FEC pins if not in use */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_RDATA1, NULL); /*SCL*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_FEC_RX_DV, NULL); /*SDA*/
+ mxc_free_iomux(MX25_PIN_FEC_RDATA1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_FEC_RX_DV, MUX_CONFIG_GPIO);
+#endif
+
+ break;
+ case 2:
+ /*I2C3*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_HSYNC), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_VSYNC), NULL);
+ mxc_free_iomux(MX25_PIN_HSYNC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_VSYNC, MUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_i2c_inactive);
+
+/*!
+ * Activate a CSPI device
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+#define SPI_PAD_CTL1 (PAD_CTL_HYS_SCHMITZ|PAD_CTL_PKE_ENABLE| \
+ PAD_CTL_100K_PU)
+#define SPI_PAD_CTL2 (PAD_CTL_HYS_SCHMITZ|PAD_CTL_PKE_ENABLE| \
+ PAD_CTL_PUE_PUD|PAD_CTL_100K_PU)
+
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX25_PIN_CSPI1_MOSI, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSPI1_MISO, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSPI1_SS0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSPI1_SS1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSPI1_SCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSPI1_RDY, MUX_CONFIG_FUNC);
+#ifndef CONFIG_CAN_FLEXCAN /* MX25 3-stack uses this pin for CAN2 */
+ mxc_request_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_ALT5); /*SS2*/
+#endif
+ mxc_request_iomux(MX25_PIN_VSTBY_ACK, MUX_CONFIG_ALT2); /*SS3*/
+
+ /* Or if VSTBY_ACK is being used */
+ /*mxc_request_iomux(MX25_PIN_NF_CE0, MUX_CONFIG_ALT1);*/ /*SS3*/
+
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_MOSI, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_MISO, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_SS0, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_SS1, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_SCLK, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSPI1_RDY, SPI_PAD_CTL1);
+#ifndef CONFIG_CAN_FLEXCAN /* MX25 3-stack uses this pin for CAN2 */
+ mxc_iomux_set_pad(MX25_PIN_GPIO_C, SPI_PAD_CTL2);
+#endif
+ mxc_iomux_set_pad(MX25_PIN_VSTBY_ACK, SPI_PAD_CTL1);
+
+ mxc_iomux_set_input(MUX_IN_CSPI1_IPP_IND_SS3_B,
+ INPUT_CTL_PATH1);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_request_iomux(MX25_PIN_LD12, MUX_CONFIG_ALT2); /*MOSI*/
+ mxc_request_iomux(MX25_PIN_LD13, MUX_CONFIG_ALT2); /*MISO*/
+ mxc_request_iomux(MX25_PIN_LD14, MUX_CONFIG_ALT2); /*SCLK*/
+ mxc_request_iomux(MX25_PIN_LD15, MUX_CONFIG_ALT2); /*RDY*/
+ mxc_request_iomux(MX25_PIN_OE_ACD, MUX_CONFIG_ALT2); /*SS0*/
+ mxc_request_iomux(MX25_PIN_CONTRAST, MUX_CONFIG_ALT2); /*SS1*/
+ mxc_request_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_ALT7); /*SS2*/
+ mxc_request_iomux(MX25_PIN_UART2_RTS, MUX_CONFIG_ALT6); /*SS3*/
+
+ mxc_iomux_set_pad(MX25_PIN_LD12, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_LD13, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_LD14, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_LD15, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_OE_ACD, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_CONTRAST, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_C, SPI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_UART2_RTS, SPI_PAD_CTL2);
+
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_CSPI_CLK_IN,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_IND_DATAREADY_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_IND_MISO, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_IND_MOSI, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_IND_SS0_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI2_IPP_IND_SS1_B,
+ INPUT_CTL_PATH0);
+ break;
+ case 2:
+ /* SPI3 */
+ mxc_request_iomux(MX25_PIN_EB0, MUX_CONFIG_ALT6); /*SS0*/
+ mxc_request_iomux(MX25_PIN_EB1, MUX_CONFIG_ALT6); /*SS1*/
+ mxc_request_iomux(MX25_PIN_CS4, MUX_CONFIG_ALT6); /*MOSI*/
+ mxc_request_iomux(MX25_PIN_CS5, MUX_CONFIG_ALT6); /*MISO*/
+ mxc_request_iomux(MX25_PIN_ECB, MUX_CONFIG_ALT6); /*SCLK*/
+ mxc_request_iomux(MX25_PIN_LBA, MUX_CONFIG_ALT6); /*RDY*/
+ mxc_request_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_ALT7); /*SS2*/
+ mxc_request_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_ALT7); /*SS3*/
+
+ mxc_iomux_set_pad(MX25_PIN_EB0, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_EB1, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CS4, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CS5, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_ECB, SPI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_LBA, SPI_PAD_CTL1);
+
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_CSPI_CLK_IN,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_DATAREADY_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_MISO, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_MOSI, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_SS0_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_SS1_B,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_SS2_B,
+ INPUT_CTL_PATH1);
+ mxc_iomux_set_input(MUX_IN_CSPI3_IPP_IND_SS3_B,
+ INPUT_CTL_PATH0);
+ break;
+ default:
+ break;
+ }
+#undef SPI_PAD_CTL1
+#undef SPI_PAD_CTL2
+}
+EXPORT_SYMBOL(gpio_spi_active);
+
+/*!
+ * Inactivate a CSPI device
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_MOSI), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_MISO), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_SS0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_SS1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_SCLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSPI1_RDY), NULL);
+#ifndef CONFIG_CAN_FLEXCAN /* MX25 3-stack uses this pin for CAN2 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_C), NULL); /*SS2*/
+#endif
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_VSTBY_ACK), NULL); /*SS3*/
+
+ mxc_free_iomux(MX25_PIN_CSPI1_MOSI, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSPI1_MISO, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSPI1_SS0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSPI1_SS1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSPI1_SCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSPI1_RDY, MUX_CONFIG_GPIO);
+#ifndef CONFIG_CAN_FLEXCAN /* MX25 3-stack uses this pin for CAN2 */
+ mxc_free_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_GPIO);
+#endif
+ mxc_free_iomux(MX25_PIN_VSTBY_ACK, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ /* SPI2 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD12), NULL); /*MOSI*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD13), NULL); /*MISO*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD14), NULL); /*SCLK*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD15), NULL); /*RDY*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_OE_ACD), NULL); /*SS0*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CONTRAST), NULL); /*SS1*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_C), NULL); /*SS2*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_UART2_RTS), NULL); /*SS3*/
+
+ mxc_free_iomux(MX25_PIN_LD12, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD13, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD14, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD15, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_OE_ACD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CONTRAST, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_UART2_RTS, MUX_CONFIG_GPIO);
+ break;
+ case 2:
+ /* SPI3 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_EB0), NULL); /*SS0*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_EB1), NULL); /*SS1*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CS4), NULL); /*MOSI*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CS5), NULL); /*MISO*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_ECB), NULL); /*SCLK*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LBA), NULL); /*RDY*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_D), NULL); /*SS2*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D9), NULL); /*SS3*/
+
+ mxc_free_iomux(MX25_PIN_EB0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_EB1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CS4, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CS5, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_ECB, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LBA, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_spi_inactive);
+
+/*!
+ * Activate LCD
+ */
+void gpio_lcdc_active(void)
+{
+ mxc_request_iomux(MX25_PIN_LD0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD6, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD7, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD8, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD9, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD10, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD11, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD12, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD13, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD14, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LD15, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_GPIO_E, MUX_CONFIG_ALT2); /*D16*/
+ mxc_request_iomux(MX25_PIN_GPIO_F, MUX_CONFIG_ALT2); /*D17*/
+ mxc_request_iomux(MX25_PIN_HSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_VSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_LSCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_OE_ACD, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CONTRAST, MUX_CONFIG_FUNC);
+
+#define LCD_PAD_CTL (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU)
+ mxc_iomux_set_pad(MX25_PIN_LD0, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD1, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD2, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD3, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD4, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD5, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD6, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD7, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD8, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD9, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD10, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD11, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD12, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD13, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD14, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD15, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_E, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_F, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_HSYNC, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_VSYNC, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LSCLK, LCD_PAD_CTL | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_OE_ACD, LCD_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CONTRAST, LCD_PAD_CTL);
+}
+EXPORT_SYMBOL(gpio_lcdc_active);
+
+/*!
+ * Inactivate LCD
+ */
+void gpio_lcdc_inactive(void)
+{
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD3), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD4), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD5), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD6), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD7), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_E), NULL); /*D16*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_F), NULL); /*D17*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_HSYNC), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_VSYNC), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LSCLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_OE_ACD), NULL);
+
+ mxc_free_iomux(MX25_PIN_LD0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD4, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD5, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD6, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD7, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD8, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD9, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD10, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD11, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD12, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD13, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD14, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_LD15, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_GPIO_E, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_GPIO_F, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_HSYNC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_VSYNC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LSCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_OE_ACD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CONTRAST, MUX_CONFIG_FUNC);
+}
+EXPORT_SYMBOL(gpio_lcdc_inactive);
+
+/*!
+ * Activate SDHC
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+#define SDHC_PAD_CTL (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | \
+ PAD_CTL_47K_PU | PAD_CTL_SRE_FAST)
+
+ switch (module) {
+ case 0:
+ /* SDHC1 */
+ mxc_request_iomux(MX25_PIN_SD1_CMD,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX25_PIN_SD1_CLK,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX25_PIN_SD1_DATA0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_SD1_DATA1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_SD1_DATA2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_SD1_DATA3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_A14, MUX_CONFIG_ALT5); /*SD1_WP*/
+ mxc_request_iomux(MX25_PIN_A15, MUX_CONFIG_ALT5); /*SD1_DET*/
+
+ mxc_iomux_set_pad(MX25_PIN_SD1_CMD, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_SD1_CLK, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_SD1_DATA0, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_SD1_DATA1, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_SD1_DATA2, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_SD1_DATA3, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_A14, PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX25_PIN_A15, PAD_CTL_DRV_NORMAL);
+
+ /* Set write protect and card detect gpio as inputs */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A14), "a14");
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A15), "a15");
+ gpio_direction_input(IOMUX_TO_GPIO(MX25_PIN_A14)); /*SD1_WP*/
+ gpio_direction_input(IOMUX_TO_GPIO(MX25_PIN_A15)); /*SD1_DET*/
+
+ break;
+ case 1:
+ /* SDHC2 */
+ mxc_request_iomux(MX25_PIN_LD8,
+ MUX_CONFIG_ALT6 | MUX_CONFIG_SION); /*CMD*/
+ mxc_request_iomux(MX25_PIN_LD9,
+ MUX_CONFIG_ALT6 | MUX_CONFIG_SION); /*CLK*/
+ mxc_request_iomux(MX25_PIN_LD10, MUX_CONFIG_ALT6); /*DAT0*/
+ mxc_request_iomux(MX25_PIN_LD11, MUX_CONFIG_ALT6); /*DAT1*/
+ mxc_request_iomux(MX25_PIN_LD12, MUX_CONFIG_ALT6); /*DAT2*/
+ mxc_request_iomux(MX25_PIN_LD13, MUX_CONFIG_ALT6); /*DAT3*/
+
+ mxc_iomux_set_pad(MX25_PIN_LD8, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD9, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD10, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD11, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD12, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_LD13, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D2, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D3, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D4, SDHC_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D5, SDHC_PAD_CTL);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Inactivate SDHC
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ /* SDHC1 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_CMD), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_CLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_DATA0), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_DATA1), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_DATA2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_SD1_DATA3), NULL);
+
+ mxc_free_iomux(MX25_PIN_SD1_CMD, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_SD1_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_SD1_DATA0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_SD1_DATA1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_SD1_DATA2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_SD1_DATA3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_A14, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_A15, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ /* SDHC2 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD8), NULL); /*CMD*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD9), NULL); /*CLK*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD10), NULL); /*DAT0*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD11), NULL); /*DAT1*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD12), NULL); /*DAT2*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_LD13), NULL); /*DAT3*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D2), NULL); /*DAT4*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D3), NULL); /*DAT5*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D4), NULL); /*DAT6*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D5), NULL); /*DAT7*/
+
+ mxc_free_iomux(MX25_PIN_LD8, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD9, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD10, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD11, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD12, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_LD13, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_GPIO);
+ 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 = 0;
+
+ ret = gpio_get_value(IOMUX_TO_GPIO(MX25_PIN_A15));
+ return ret;
+}
+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;
+
+ rc = gpio_get_value(IOMUX_TO_GPIO(MX25_PIN_A14));
+ return rc;
+}
+EXPORT_SYMBOL(sdhc_write_protect);
+
+/*
+ * USB Host2
+ *
+ * This configuration uses the on-chip FS/LS serial transceiver.
+ * USBPHY2_{DP,DM} pins are not muxed.
+ * We just need to grab USBH2_PWR, USBH2_OC and the Bluetooth/USB
+ * mux control signal.
+ */
+int gpio_usbh2_active(void)
+{
+ if (mxc_request_iomux(MX25_PIN_D9, MUX_CONFIG_ALT6) || /* PWR */
+ mxc_request_iomux(MX25_PIN_D8, MUX_CONFIG_ALT6) || /* OC */
+ mxc_request_iomux(MX25_PIN_A21, MUX_CONFIG_ALT5)) { /* BT_USB_CS */
+ return -EINVAL;
+ }
+
+ /*
+ * This pin controls the mux that switches between
+ * the J18 connector and the on-board bluetooth module.
+ * dir: 0 = out
+ * pin: 0 = J18, 1 = BT
+ */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A21), "a21");
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_A21), 0);
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A21), 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_usbh2_active);
+
+void gpio_usbh2_inactive(void)
+{
+ mxc_free_iomux(MX25_PIN_D9, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_D8, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_A21, MUX_CONFIG_GPIO);
+}
+
+/*
+ * USB OTG UTMI
+ *
+ * This configuration uses the on-chip UTMI transceiver.
+ * USBPHY1_{VBUS,DP,DM,UID,RREF} pins are not muxed.
+ * We just need to grab the USBOTG_PWR and USBOTG_OC pins.
+ */
+int gpio_usbotg_utmi_active(void)
+{
+ if (mxc_request_iomux(MX25_PIN_GPIO_A, MUX_CONFIG_ALT2) || /* PWR */
+ mxc_request_iomux(MX25_PIN_GPIO_B, MUX_CONFIG_ALT2)) { /* OC */
+ return -EINVAL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(gpio_usbotg_utmi_active);
+
+void gpio_usbotg_utmi_inactive(void)
+{
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_A), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_B), NULL);
+
+ mxc_free_iomux(MX25_PIN_GPIO_A, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_GPIO_B, MUX_CONFIG_GPIO);
+}
+EXPORT_SYMBOL(gpio_usbotg_utmi_inactive);
+
+/*!
+ * Activate camera sensor
+ */
+void gpio_sensor_active(void)
+{
+ mxc_request_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D6, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D7, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D8, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_HSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_MCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_PIXCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_CSI_VSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX25_PIN_A19, MUX_CONFIG_ALT5); /*CSI_PWDN*/
+ mxc_request_iomux(MX25_PIN_A20, MUX_CONFIG_ALT5); /*CMOS_RST*/
+
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A19), "a19");
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A20), "a20");
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_A19), 0); /*CSI_PWDN*/
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A19), 0);
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_A20), 0); /*CMOS_RST*/
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A20), 0);
+ mdelay(20);
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_A20), 1);
+
+#define CSI_PAD_CTL1 (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU)
+#define CSI_PAD_CTL2 (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
+ PAD_CTL_100K_PU)
+
+ mxc_iomux_set_pad(MX25_PIN_CSI_D2, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D3, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D4, CSI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D5, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D6, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D7, CSI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D8, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D9, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_HSYNC, CSI_PAD_CTL1);
+ mxc_iomux_set_pad(MX25_PIN_CSI_MCLK, PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_CSI_PIXCLK, CSI_PAD_CTL2);
+ mxc_iomux_set_pad(MX25_PIN_CSI_VSYNC, CSI_PAD_CTL1);
+}
+EXPORT_SYMBOL(gpio_sensor_active);
+
+/*!
+ * Inactivate camera sensor
+ */
+void gpio_sensor_inactive(void)
+{
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D2), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D3), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D4), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D5), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D6), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D7), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D8), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_D9), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_HSYNC), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_MCLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_PIXCLK), NULL);
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_CSI_VSYNC), NULL);
+
+ mxc_free_iomux(MX25_PIN_A19, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_A20, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D6, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D7, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D8, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_HSYNC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_MCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_PIXCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_CSI_VSYNC, MUX_CONFIG_GPIO);
+}
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Activate ESAI ports to enable surround sound I/O
+ */
+void gpio_activate_esai_ports(void)
+{
+ mxc_request_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_ALT3); /*SCKR*/
+ mxc_request_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_ALT3); /*FSR*/
+ mxc_request_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_ALT3); /*HCKR*/
+ mxc_request_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_ALT3); /*SCKT*/
+ mxc_request_iomux(MX25_PIN_CSI_D6, MUX_CONFIG_ALT3); /*FST*/
+ mxc_request_iomux(MX25_PIN_CSI_D7, MUX_CONFIG_ALT3); /*HCKT*/
+ mxc_request_iomux(MX25_PIN_CSI_D8, MUX_CONFIG_ALT3); /*TX5_RX0*/
+ mxc_request_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_ALT3); /*TX4_RX1*/
+ mxc_request_iomux(MX25_PIN_CSI_MCLK, MUX_CONFIG_ALT3); /*TX3_RX2*/
+ mxc_request_iomux(MX25_PIN_CSI_VSYNC, MUX_CONFIG_ALT3); /*TX2_RX3*/
+ mxc_request_iomux(MX25_PIN_CSI_HSYNC, MUX_CONFIG_ALT3); /*TX1*/
+ mxc_request_iomux(MX25_PIN_CSI_PIXCLK, MUX_CONFIG_ALT3); /*TX0*/
+
+#define ESAI_PAD_CTL (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
+ PAD_CTL_100K_PU | PAD_CTL_PUE_PUD)
+ mxc_iomux_set_pad(MX25_PIN_CSI_D2, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D3, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D4, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D5, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D6, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D7, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D8, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_D9, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_MCLK, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_VSYNC, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_HSYNC, ESAI_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_CSI_PIXCLK, ESAI_PAD_CTL);
+
+#undef ESAI_PAD_CTL
+}
+EXPORT_SYMBOL(gpio_activate_esai_ports);
+
+/*!
+ * Inactivate ESAI ports to disable surround sound I/O
+ */
+void gpio_deactivate_esai_ports(void)
+{
+ mxc_free_iomux(MX25_PIN_CSI_D2, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D3, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D4, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D5, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D6, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D7, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D8, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_D9, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_MCLK, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_VSYNC, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_HSYNC, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_CSI_PIXCLK, MUX_CONFIG_FUNC);
+}
+EXPORT_SYMBOL(gpio_deactivate_esai_ports);
+
+
+/*!
+ * Activate CAN
+ */
+void gpio_can_active(int id)
+{
+#define CAN_PAD_CTL (PAD_CTL_DRV_3_3V | PAD_CTL_PKE_NONE | PAD_CTL_ODE_CMOS | \
+ PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)
+#define CAN_PAD_IN_CTL (PAD_CTL_HYS_CMOS | PAD_CTL_PKE_NONE)
+
+ switch (id) {
+ case 0:
+ /* CAN1 */
+ mxc_request_iomux(MX25_PIN_GPIO_A, MUX_CONFIG_ALT6); /*TXCAN*/
+ mxc_request_iomux(MX25_PIN_GPIO_B, MUX_CONFIG_ALT6); /*RXCAN*/
+
+ mxc_iomux_set_pad(MX25_PIN_GPIO_A, CAN_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_B, CAN_PAD_IN_CTL);
+
+ mxc_iomux_set_input(MUX_IN_CAN1_IPP_IND_CANRX, INPUT_CTL_PATH1);
+ break;
+ case 1:
+ /* CAN2 */
+ mxc_request_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_ALT6); /*TXCAN*/
+ mxc_request_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_ALT6); /*RXCAN*/
+ mxc_request_iomux(MX25_PIN_D14, MUX_CONFIG_ALT5); /*PWDN*/
+
+ mxc_iomux_set_pad(MX25_PIN_GPIO_C, CAN_PAD_CTL);
+ mxc_iomux_set_pad(MX25_PIN_GPIO_D, CAN_PAD_IN_CTL);
+ mxc_iomux_set_pad(MX25_PIN_D14, CAN_PAD_CTL);
+
+ mxc_iomux_set_input(MUX_IN_CAN2_IPP_IND_CANRX, INPUT_CTL_PATH1);
+
+ /* Configure CAN_PWDN as output */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_D14), "d14");
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_D14), 0);
+
+ /* Enable input by setting PWDN/TLE6250.INH low (gpio4 bit6) */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D14), 0);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_can_active);
+
+/*!
+ * Inactivate CAN
+ */
+void gpio_can_inactive(int id)
+{
+ switch (id) {
+ case 0:
+ /* CAN1 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_A), NULL); /*TXCAN*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_B), NULL); /*RXCAN*/
+
+ mxc_free_iomux(MX25_PIN_GPIO_A, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_GPIO_B, MUX_CONFIG_FUNC);
+
+ break;
+ case 1:
+ /* CAN2 */
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_C), NULL); /*TXCAN*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_GPIO_D), NULL); /*RXCAN*/
+
+ mxc_free_iomux(MX25_PIN_GPIO_C, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX25_PIN_GPIO_D, MUX_CONFIG_FUNC);
+
+ /* Disable input by setting PWDN/TLE6250.INH high */
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D14), 1);
+ mxc_free_iomux(MX25_PIN_D14, MUX_CONFIG_ALT5);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(gpio_can_inactive);
+
+/*!
+ * This function activates DAM port 4 to enable
+ * audio I/O.
+ */
+void gpio_activate_audio_ports(void)
+{
+ mxc_request_iomux(MX25_PIN_EB0, MUX_CONFIG_ALT4); /*SSI4_STXD*/
+ mxc_request_iomux(MX25_PIN_EB1, MUX_CONFIG_ALT4); /*SSI4_SRXD*/
+ mxc_request_iomux(MX25_PIN_RW, MUX_CONFIG_ALT4); /*SSI4_STXFS*/
+ mxc_request_iomux(MX25_PIN_OE, MUX_CONFIG_ALT4); /*SSI4_SCK*/
+ mxc_request_iomux(MX25_PIN_A10, MUX_CONFIG_ALT5); /*HP_DEC*/
+ mxc_request_iomux(MX25_PIN_D13, MUX_CONFIG_ALT5); /*AMP_SHUTDOWN*/
+
+ mxc_iomux_set_pad(MX25_PIN_EB0, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_EB1, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_RW, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_OE, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX25_PIN_D13, PAD_CTL_DRV_3_3V);
+
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A10), "a10");
+ gpio_direction_input(IOMUX_TO_GPIO(MX25_PIN_A10));
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_D13), "d13");
+ gpio_direction_output(IOMUX_TO_GPIO(MX25_PIN_D13), 0);
+}
+EXPORT_SYMBOL(gpio_activate_audio_ports);
+
+/*!
+ * This function deactivates DAM port 4 for
+ * audio I/O
+ */
+void gpio_deactive_audio_ports(void)
+{
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_EB0), NULL); /*SSI4_STXD*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_EB1), NULL); /*SSI4_SRXD*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_RW), NULL); /*SSI4_STXFS*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_OE), NULL); /*SSI4_SCK*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_A10), NULL); /*HP_DEC*/
+ gpio_request(IOMUX_TO_GPIO(MX25_PIN_D13), NULL); /*AMP_SHUTDOWN*/
+
+ mxc_free_iomux(MX25_PIN_EB0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_EB1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_RW, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_OE, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_A10, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX25_PIN_D13, MUX_CONFIG_GPIO);
+}
+EXPORT_SYMBOL(gpio_deactive_audio_ports);
+
+int headphone_det_status(void)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX25_PIN_A10));
+}
+EXPORT_SYMBOL(headphone_det_status);
+
+void sgtl5000_enable_amp(void)
+{
+ gpio_set_value(IOMUX_TO_GPIO(MX25_PIN_D13), 1);
+}
+EXPORT_SYMBOL(sgtl5000_enable_amp);
diff --git a/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c b/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c
new file mode 100644
index 000000000000..6c857d00f2e5
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25_3stack_pmic_mc34704.c
@@ -0,0 +1,147 @@
+/*
+ * mx25-3stack-pmic-mc34704.c -- i.MX25 3STACK Driver for MC34704 PMIC
+ */
+ /*
+ * Copyright (C) 2009-2010 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/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/pmic_external.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc34704/core.h>
+#include "iomux.h"
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+struct mc34704;
+
+static struct regulator_consumer_supply rcpu_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "0-000a",
+ },
+};
+
+static struct regulator_consumer_supply rddr_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDIO",
+ .dev_name = "0-000a",
+ },
+};
+
+static struct regulator_init_data rbklt_init = {
+ .constraints = {
+ .name = "REG1_BKLT",
+ .min_uV =
+ mV_to_uV(REG1_V_MV * (1000 + REG1_DVS_MIN_PCT * 10) /
+ 1000),
+ .max_uV =
+ mV_to_uV(REG1_V_MV * (1000 + REG1_DVS_MAX_PCT * 10) /
+ 1000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ }
+};
+
+static struct regulator_init_data rcpu_init = {
+ .constraints = {
+ .name = "REG2_CPU",
+ .min_uV =
+ mV_to_uV(REG2_V_MV * (1000 + REG2_DVS_MIN_PCT * 10) /
+ 1000),
+ .max_uV =
+ mV_to_uV(REG2_V_MV * (1000 + REG2_DVS_MAX_PCT * 10) /
+ 1000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rcpu_consumers),
+ .consumer_supplies = rcpu_consumers,
+};
+
+static struct regulator_init_data rcore_init = {
+ .constraints = {
+ .name = "REG3_CORE",
+ .min_uV =
+ mV_to_uV(REG3_V_MV * (1000 + REG3_DVS_MIN_PCT * 10) /
+ 1000),
+ .max_uV =
+ mV_to_uV(REG3_V_MV * (1000 + REG3_DVS_MAX_PCT * 10) /
+ 1000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ }
+};
+
+static struct regulator_init_data rddr_init = {
+ .constraints = {
+ .name = "REG4_DDR",
+ .min_uV =
+ mV_to_uV(REG4_V_MV * (1000 + REG4_DVS_MIN_PCT * 10) /
+ 1000),
+ .max_uV =
+ mV_to_uV(REG4_V_MV * (1000 + REG4_DVS_MAX_PCT * 10) /
+ 1000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rddr_consumers),
+ .consumer_supplies = rddr_consumers,
+};
+
+static struct regulator_init_data rpers_init = {
+ .constraints = {
+ .name = "REG5_PERS",
+ .min_uV =
+ mV_to_uV(REG5_V_MV * (1000 + REG5_DVS_MIN_PCT * 10) /
+ 1000),
+ .max_uV =
+ mV_to_uV(REG5_V_MV * (1000 + REG5_DVS_MAX_PCT * 10) /
+ 1000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ }
+};
+
+static int mc34704_regulator_init(struct mc34704 *mc34704)
+{
+ mc34704_register_regulator(mc34704, MC34704_BKLT, &rbklt_init);
+ mc34704_register_regulator(mc34704, MC34704_CPU, &rcpu_init);
+ mc34704_register_regulator(mc34704, MC34704_CORE, &rcore_init);
+ mc34704_register_regulator(mc34704, MC34704_DDR, &rddr_init);
+ mc34704_register_regulator(mc34704, MC34704_PERS, &rpers_init);
+
+ return 0;
+}
+
+static struct mc34704_platform_data mc34704_plat = {
+ .init = mc34704_regulator_init,
+};
+
+static struct i2c_board_info __initdata mc34704_i2c_device = {
+ .type = "mc34704",
+ .addr = 0x54,
+ .platform_data = &mc34704_plat,
+};
+
+int __init mx25_3stack_init_mc34704(void)
+{
+ return i2c_register_board_info(0, &mc34704_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx25/mx25_pins.h b/arch/arm/mach-mx25/mx25_pins.h
new file mode 100644
index 000000000000..ce11f8252ea6
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25_pins.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25_PINS_H__
+#define __ASM_ARCH_MXC_MX25_PINS_H__
+
+/*!
+ * @file arch-mxc/mx25_pins.h
+ *
+ * @brief MX25 I/O Pin List
+ *
+ * @ingroup GPIO_MX25
+ */
+
+#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. Similar field
+ * definitions are used for the pad control register. For example,
+ * MX25_PIN_A14 is defined in the enumeration:
+ * ( 0x10 << MUX_I) | ( 0x230 << PAD_I)
+ * So the absolute address is: IOMUX_module_base + 0x10.
+ * The pad control register offset is: 0x230.
+ */
+
+/*!
+ * 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 */
+
+enum iomux_pins {
+ MX25_PIN_A10 = _MXC_BUILD_GPIO_PIN(3, 0, 0x8, 0x0),
+ MX25_PIN_A13 = _MXC_BUILD_GPIO_PIN(3, 1, 0x0c, 0x22C),
+ MX25_PIN_A14 = _MXC_BUILD_GPIO_PIN(1, 0, 0x10, 0x230),
+ MX25_PIN_A15 = _MXC_BUILD_GPIO_PIN(1, 1, 0x14, 0x234),
+ MX25_PIN_A16 = _MXC_BUILD_GPIO_PIN(1, 2, 0x18, 0x0),
+ MX25_PIN_A17 = _MXC_BUILD_GPIO_PIN(1, 3, 0x1c, 0x238),
+ MX25_PIN_A18 = _MXC_BUILD_GPIO_PIN(1, 4, 0x20, 0x23c),
+ MX25_PIN_A19 = _MXC_BUILD_GPIO_PIN(1, 5, 0x24, 0x240),
+ MX25_PIN_A20 = _MXC_BUILD_GPIO_PIN(1, 6, 0x28, 0x244),
+ MX25_PIN_A21 = _MXC_BUILD_GPIO_PIN(1, 7, 0x2c, 0x248),
+ MX25_PIN_A22 = _MXC_BUILD_GPIO_PIN(1, 8, 0x30, 0x0),
+ MX25_PIN_A23 = _MXC_BUILD_GPIO_PIN(1, 9, 0x34, 0x24c),
+ MX25_PIN_A24 = _MXC_BUILD_GPIO_PIN(1, 10, 0x38, 0x250),
+ MX25_PIN_A25 = _MXC_BUILD_GPIO_PIN(1, 11, 0x3c, 0x254),
+ MX25_PIN_EB0 = _MXC_BUILD_GPIO_PIN(1, 12, 0x40, 0x258),
+ MX25_PIN_EB1 = _MXC_BUILD_GPIO_PIN(1, 13, 0x44, 0x25c),
+ MX25_PIN_OE = _MXC_BUILD_GPIO_PIN(1, 14, 0x48, 0x260),
+ MX25_PIN_CS0 = _MXC_BUILD_GPIO_PIN(3, 2, 0x4c, 0x0),
+ MX25_PIN_CS1 = _MXC_BUILD_GPIO_PIN(3, 3, 0x50, 0x0),
+ MX25_PIN_CS4 = _MXC_BUILD_GPIO_PIN(2, 20, 0x54, 0x264),
+ MX25_PIN_CS5 = _MXC_BUILD_GPIO_PIN(2, 21, 0x58, 0x268),
+ MX25_PIN_NF_CE0 = _MXC_BUILD_GPIO_PIN(2, 22, 0x5c, 0x26c),
+ MX25_PIN_ECB = _MXC_BUILD_GPIO_PIN(2, 23, 0x60, 0x270),
+ MX25_PIN_LBA = _MXC_BUILD_GPIO_PIN(2, 24, 0x64, 0x274),
+ MX25_PIN_BCLK = _MXC_BUILD_GPIO_PIN(3, 4, 0x68, 0x0),
+ MX25_PIN_RW = _MXC_BUILD_GPIO_PIN(2, 25, 0x6c, 0x278),
+ MX25_PIN_NFWE_B = _MXC_BUILD_GPIO_PIN(2, 26, 0x70, 0x0),
+ MX25_PIN_NFRE_B = _MXC_BUILD_GPIO_PIN(2, 27, 0x74, 0x0),
+ MX25_PIN_NFALE = _MXC_BUILD_GPIO_PIN(2, 28, 0x78, 0x0),
+ MX25_PIN_NFCLE = _MXC_BUILD_GPIO_PIN(2, 29, 0x7c, 0x0),
+ MX25_PIN_NFWP_B = _MXC_BUILD_GPIO_PIN(2, 30, 0x80, 0x0),
+ MX25_PIN_NFRB = _MXC_BUILD_GPIO_PIN(2, 31, 0x84, 0x27c),
+ MX25_PIN_D15 = _MXC_BUILD_GPIO_PIN(3, 5, 0x88, 0x280),
+ MX25_PIN_D14 = _MXC_BUILD_GPIO_PIN(3, 6, 0x8c, 0x284),
+ MX25_PIN_D13 = _MXC_BUILD_GPIO_PIN(3, 7, 0x90, 0x288),
+ MX25_PIN_D12 = _MXC_BUILD_GPIO_PIN(3, 8, 0x94, 0x28c),
+ MX25_PIN_D11 = _MXC_BUILD_GPIO_PIN(3, 9, 0x98, 0x290),
+ MX25_PIN_D10 = _MXC_BUILD_GPIO_PIN(3, 10, 0x9c, 0x294),
+ MX25_PIN_D9 = _MXC_BUILD_GPIO_PIN(3, 11, 0xa0, 0x298),
+ MX25_PIN_D8 = _MXC_BUILD_GPIO_PIN(3, 12, 0xa4, 0x29c),
+ MX25_PIN_D7 = _MXC_BUILD_GPIO_PIN(3, 13, 0xa8, 0x2a0),
+ MX25_PIN_D6 = _MXC_BUILD_GPIO_PIN(3, 14, 0xac, 0x2a4),
+ MX25_PIN_D5 = _MXC_BUILD_GPIO_PIN(3, 15, 0xb0, 0x2a8),
+ MX25_PIN_D4 = _MXC_BUILD_GPIO_PIN(3, 16, 0xb4, 0x2ac),
+ MX25_PIN_D3 = _MXC_BUILD_GPIO_PIN(3, 17, 0xb8, 0x2b0),
+ MX25_PIN_D2 = _MXC_BUILD_GPIO_PIN(3, 18, 0xbc, 0x2b4),
+ MX25_PIN_D1 = _MXC_BUILD_GPIO_PIN(3, 19, 0xc0, 0x2b8),
+ MX25_PIN_D0 = _MXC_BUILD_GPIO_PIN(3, 20, 0xc4, 0x2bc),
+ MX25_PIN_LD0 = _MXC_BUILD_GPIO_PIN(1, 15, 0xc8, 0x2c0),
+ MX25_PIN_LD1 = _MXC_BUILD_GPIO_PIN(1, 16, 0xcc, 0x2c4),
+ MX25_PIN_LD2 = _MXC_BUILD_GPIO_PIN(1, 17, 0xd0, 0x2c8),
+ MX25_PIN_LD3 = _MXC_BUILD_GPIO_PIN(1, 18, 0xd4, 0x2cc),
+ MX25_PIN_LD4 = _MXC_BUILD_GPIO_PIN(1, 19, 0xd8, 0x2d0),
+ MX25_PIN_LD5 = _MXC_BUILD_GPIO_PIN(0, 19, 0xdc, 0x2d4),
+ MX25_PIN_LD6 = _MXC_BUILD_GPIO_PIN(0, 20, 0xe0, 0x2d8),
+ MX25_PIN_LD7 = _MXC_BUILD_GPIO_PIN(0, 21, 0xe4, 0x2dc),
+ MX25_PIN_LD8 = _MXC_BUILD_NON_GPIO_PIN(0xe8, 0x2e0),
+ MX25_PIN_LD9 = _MXC_BUILD_NON_GPIO_PIN(0xec, 0x2e4),
+ MX25_PIN_LD10 = _MXC_BUILD_NON_GPIO_PIN(0xf0, 0x2e8),
+ MX25_PIN_LD11 = _MXC_BUILD_NON_GPIO_PIN(0xf4, 0x2ec),
+ MX25_PIN_LD12 = _MXC_BUILD_NON_GPIO_PIN(0xf8, 0x2f0),
+ MX25_PIN_LD13 = _MXC_BUILD_NON_GPIO_PIN(0xfc, 0x2f4),
+ MX25_PIN_LD14 = _MXC_BUILD_NON_GPIO_PIN(0x100, 0x2f8),
+ MX25_PIN_LD15 = _MXC_BUILD_NON_GPIO_PIN(0x104, 0x2fc),
+ MX25_PIN_HSYNC = _MXC_BUILD_GPIO_PIN(0, 22, 0x108, 0x300),
+ MX25_PIN_VSYNC = _MXC_BUILD_GPIO_PIN(0, 23, 0x10c, 0x304),
+ MX25_PIN_LSCLK = _MXC_BUILD_GPIO_PIN(0, 24, 0x110, 0x308),
+ MX25_PIN_OE_ACD = _MXC_BUILD_GPIO_PIN(0, 25, 0x114, 0x30c),
+ MX25_PIN_CONTRAST = _MXC_BUILD_NON_GPIO_PIN(0x118, 0x310),
+ MX25_PIN_PWM = _MXC_BUILD_GPIO_PIN(0, 26, 0x11c, 0x314),
+ MX25_PIN_CSI_D2 = _MXC_BUILD_GPIO_PIN(0, 27, 0x120, 0x318),
+ MX25_PIN_CSI_D3 = _MXC_BUILD_GPIO_PIN(0, 28, 0x124, 0x31c),
+ MX25_PIN_CSI_D4 = _MXC_BUILD_GPIO_PIN(0, 29, 0x128, 0x320),
+ MX25_PIN_CSI_D5 = _MXC_BUILD_GPIO_PIN(0, 30, 0x12c, 0x324),
+ MX25_PIN_CSI_D6 = _MXC_BUILD_GPIO_PIN(0, 31, 0x130, 0x328),
+ MX25_PIN_CSI_D7 = _MXC_BUILD_GPIO_PIN(0, 6, 0x134, 0x32c),
+ MX25_PIN_CSI_D8 = _MXC_BUILD_GPIO_PIN(0, 7, 0x138, 0x330),
+ MX25_PIN_CSI_D9 = _MXC_BUILD_GPIO_PIN(3, 21, 0x13c, 0x334),
+ MX25_PIN_CSI_MCLK = _MXC_BUILD_GPIO_PIN(0, 8, 0x140, 0x338),
+ MX25_PIN_CSI_VSYNC = _MXC_BUILD_GPIO_PIN(0, 9, 0x144, 0x33c),
+ MX25_PIN_CSI_HSYNC = _MXC_BUILD_GPIO_PIN(0, 10, 0x148, 0x340),
+ MX25_PIN_CSI_PIXCLK = _MXC_BUILD_GPIO_PIN(0, 11, 0x14c, 0x344),
+ MX25_PIN_I2C1_CLK = _MXC_BUILD_GPIO_PIN(0, 12, 0x150, 0x348),
+ MX25_PIN_I2C1_DAT = _MXC_BUILD_GPIO_PIN(0, 13, 0x154, 0x34c),
+ MX25_PIN_CSPI1_MOSI = _MXC_BUILD_GPIO_PIN(0, 14, 0x158, 0x350),
+ MX25_PIN_CSPI1_MISO = _MXC_BUILD_GPIO_PIN(0, 15, 0x15c, 0x354),
+ MX25_PIN_CSPI1_SS0 = _MXC_BUILD_GPIO_PIN(0, 16, 0x160, 0x358),
+ MX25_PIN_CSPI1_SS1 = _MXC_BUILD_GPIO_PIN(0, 17, 0x164, 0x35c),
+ MX25_PIN_CSPI1_SCLK = _MXC_BUILD_GPIO_PIN(0, 18, 0x168, 0x360),
+ MX25_PIN_CSPI1_RDY = _MXC_BUILD_GPIO_PIN(1, 22, 0x16c, 0x364),
+ MX25_PIN_UART1_RXD = _MXC_BUILD_GPIO_PIN(3, 22, 0x170, 0x368),
+ MX25_PIN_UART1_TXD = _MXC_BUILD_GPIO_PIN(3, 23, 0x174, 0x36c),
+ MX25_PIN_UART1_RTS = _MXC_BUILD_GPIO_PIN(3, 24, 0x178, 0x370),
+ MX25_PIN_UART1_CTS = _MXC_BUILD_GPIO_PIN(3, 25, 0x17c, 0x374),
+ MX25_PIN_UART2_RXD = _MXC_BUILD_GPIO_PIN(3, 26, 0x180, 0x378),
+ MX25_PIN_UART2_TXD = _MXC_BUILD_GPIO_PIN(3, 27, 0x184, 0x37c),
+ MX25_PIN_UART2_RTS = _MXC_BUILD_GPIO_PIN(3, 28, 0x188, 0x380),
+ MX25_PIN_UART2_CTS = _MXC_BUILD_GPIO_PIN(3, 29, 0x18c, 0x384),
+ MX25_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN(1, 23, 0x190, 0x388),
+ MX25_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN(1, 24, 0x194, 0x38c),
+ MX25_PIN_SD1_DATA0 = _MXC_BUILD_GPIO_PIN(1, 25, 0x198, 0x390),
+ MX25_PIN_SD1_DATA1 = _MXC_BUILD_GPIO_PIN(1, 26, 0x19c, 0x394),
+ MX25_PIN_SD1_DATA2 = _MXC_BUILD_GPIO_PIN(1, 27, 0x1a0, 0x398),
+ MX25_PIN_SD1_DATA3 = _MXC_BUILD_GPIO_PIN(1, 28, 0x1a4, 0x39c),
+ MX25_PIN_KPP_ROW0 = _MXC_BUILD_GPIO_PIN(1, 29, 0x1a8, 0x3a0),
+ MX25_PIN_KPP_ROW1 = _MXC_BUILD_GPIO_PIN(1, 30, 0x1ac, 0x3a4),
+ MX25_PIN_KPP_ROW2 = _MXC_BUILD_GPIO_PIN(1, 31, 0x1b0, 0x3a8),
+ MX25_PIN_KPP_ROW3 = _MXC_BUILD_GPIO_PIN(2, 0, 0x1b4, 0x3ac),
+ MX25_PIN_KPP_COL0 = _MXC_BUILD_GPIO_PIN(2, 1, 0x1b8, 0x3b0),
+ MX25_PIN_KPP_COL1 = _MXC_BUILD_GPIO_PIN(2, 2, 0x1bc, 0x3b4),
+ MX25_PIN_KPP_COL2 = _MXC_BUILD_GPIO_PIN(2, 3, 0x1c0, 0x3b8),
+ MX25_PIN_KPP_COL3 = _MXC_BUILD_GPIO_PIN(2, 4, 0x1c4, 0x3bc),
+ MX25_PIN_FEC_MDC = _MXC_BUILD_GPIO_PIN(2, 5, 0x1c8, 0x3c0),
+ MX25_PIN_FEC_MDIO = _MXC_BUILD_GPIO_PIN(2, 6, 0x1cc, 0x3c4),
+ MX25_PIN_FEC_TDATA0 = _MXC_BUILD_GPIO_PIN(2, 7, 0x1d0, 0x3c8),
+ MX25_PIN_FEC_TDATA1 = _MXC_BUILD_GPIO_PIN(2, 8, 0x1d4, 0x3cc),
+ MX25_PIN_FEC_TX_EN = _MXC_BUILD_GPIO_PIN(2, 9, 0x1d8, 0x3d0),
+ MX25_PIN_FEC_RDATA0 = _MXC_BUILD_GPIO_PIN(2, 10, 0x1dc, 0x3d4),
+ MX25_PIN_FEC_RDATA1 = _MXC_BUILD_GPIO_PIN(2, 11, 0x1e0, 0x3d8),
+ MX25_PIN_FEC_RX_DV = _MXC_BUILD_GPIO_PIN(2, 12, 0x1e4, 0x3dc),
+ MX25_PIN_FEC_TX_CLK = _MXC_BUILD_GPIO_PIN(2, 13, 0x1e8, 0x3e0),
+ MX25_PIN_RTCK = _MXC_BUILD_GPIO_PIN(2, 14, 0x1ec, 0x3e4),
+ MX25_PIN_DE_B = _MXC_BUILD_GPIO_PIN(1, 20, 0x1f0, 0x3ec),
+ MX25_PIN_TDO = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x3e8),
+ MX25_PIN_GPIO_A = _MXC_BUILD_GPIO_PIN(0, 0, 0x1f4, 0x3f0),
+ MX25_PIN_GPIO_B = _MXC_BUILD_GPIO_PIN(0, 1, 0x1f8, 0x3f4),
+ MX25_PIN_GPIO_C = _MXC_BUILD_GPIO_PIN(0, 2, 0x1fc, 0x3f8),
+ MX25_PIN_GPIO_D = _MXC_BUILD_GPIO_PIN(0, 3, 0x200, 0x3fc),
+ MX25_PIN_GPIO_E = _MXC_BUILD_GPIO_PIN(0, 4, 0x204, 0x400),
+ MX25_PIN_GPIO_F = _MXC_BUILD_GPIO_PIN(0, 5, 0x208, 0x404),
+ MX25_PIN_EXT_ARMCLK = _MXC_BUILD_GPIO_PIN(2, 15, 0x20c, 0x0),
+ MX25_PIN_UPLL_BYPCLK = _MXC_BUILD_GPIO_PIN(2, 16, 0x210, 0x0),
+ MX25_PIN_VSTBY_REQ = _MXC_BUILD_GPIO_PIN(2, 17, 0x214, 0x408),
+ MX25_PIN_VSTBY_ACK = _MXC_BUILD_GPIO_PIN(2, 18, 0x218, 0x40c),
+ MX25_PIN_POWER_FAIL = _MXC_BUILD_GPIO_PIN(2, 19, 0x21c, 0x410),
+ MX25_PIN_CLKO = _MXC_BUILD_GPIO_PIN(1, 21, 0x220, 0x414),
+ MX25_PIN_BOOT_MODE0 = _MXC_BUILD_GPIO_PIN(3, 30, 0x224, 0x0),
+ MX25_PIN_BOOT_MODE1 = _MXC_BUILD_GPIO_PIN(3, 31, 0x228, 0x0),
+
+ MX25_PIN_CTL_GRP_DVS_MISC = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x418),
+ MX25_PIN_CTL_GRP_DSE_FEC = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x41c),
+ MX25_PIN_CTL_GRP_DVS_JTAG = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x420),
+ MX25_PIN_CTL_GRP_DSE_NFC = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x424),
+ MX25_PIN_CTL_GRP_DSE_CSI = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x428),
+ MX25_PIN_CTL_GRP_DSE_WEIM = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x42c),
+ MX25_PIN_CTL_GRP_DSE_DDR = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x430),
+ MX25_PIN_CTL_GRP_DVS_CRM = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x434),
+ MX25_PIN_CTL_GRP_DSE_KPP = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x438),
+ MX25_PIN_CTL_GRP_DSE_SDHC1 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x43c),
+ MX25_PIN_CTL_GRP_DSE_LCD = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x440),
+ MX25_PIN_CTL_GRP_DSE_UART = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x444),
+ MX25_PIN_CTL_GRP_DVS_NFC = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x448),
+ MX25_PIN_CTL_GRP_DVS_CSI = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x44c),
+ MX25_PIN_CTL_GRP_DSE_CSPI1 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x450),
+ MX25_PIN_CTL_GRP_DDRTYPE = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x454),
+ MX25_PIN_CTL_GRP_DVS_SDHC1 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x458),
+ MX25_PIN_CTL_GRP_DVS_LCD = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x45c)
+};
+
+#endif
+#endif
diff --git a/arch/arm/mach-mx25/pm.c b/arch/arm/mach-mx25/pm.c
new file mode 100644
index 000000000000..690bce795389
--- /dev/null
+++ b/arch/arm/mach-mx25/pm.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009-2010 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>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX25 i.MX25 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx25/pm.c
+ * @brief This file contains suspend operations
+ *
+ * @ingroup MSL_MX25
+ */
+static unsigned int cgcr0, cgcr1, cgcr2;
+
+static int mx25_suspend_enter(suspend_state_t state)
+{
+ unsigned int reg;
+
+ 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;
+ }
+ /* Executing CP15 (Wait-for-Interrupt) Instruction */
+ cpu_do_idle();
+
+ reg = (__raw_readl(MXC_CCM_CGCR0) & ~MXC_CCM_CGCR0_STOP_MODE_MASK) |
+ cgcr0;
+ __raw_writel(reg, MXC_CCM_CGCR0);
+
+ reg = (__raw_readl(MXC_CCM_CGCR1) & ~MXC_CCM_CGCR1_STOP_MODE_MASK) |
+ cgcr1;
+ __raw_writel(reg, MXC_CCM_CGCR1);
+
+ reg = (__raw_readl(MXC_CCM_CGCR2) & ~MXC_CCM_CGCR2_STOP_MODE_MASK) |
+ cgcr2;
+ __raw_writel(reg, MXC_CCM_CGCR2);
+
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx25_suspend_prepare(void)
+{
+ cgcr0 = __raw_readl(MXC_CCM_CGCR0) & MXC_CCM_CGCR0_STOP_MODE_MASK;
+ cgcr1 = __raw_readl(MXC_CCM_CGCR1) & MXC_CCM_CGCR1_STOP_MODE_MASK;
+ cgcr2 = __raw_readl(MXC_CCM_CGCR2) & MXC_CCM_CGCR2_STOP_MODE_MASK;
+
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx25_suspend_finish(void)
+{
+}
+
+static int mx25_pm_valid(suspend_state_t state)
+{
+ return state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX;
+}
+
+struct platform_suspend_ops mx25_suspend_ops = {
+ .valid = mx25_pm_valid,
+ .prepare = mx25_suspend_prepare,
+ .enter = mx25_suspend_enter,
+ .finish = mx25_suspend_finish,
+};
+
+static int __init mx25_pm_init(void)
+{
+ pr_info("Static Power Management for Freescale i.MX25\n");
+ suspend_set_ops(&mx25_suspend_ops);
+
+ return 0;
+}
+
+late_initcall(mx25_pm_init);
diff --git a/arch/arm/mach-mx25/sdma_script_code.h b/arch/arm/mach-mx25/sdma_script_code.h
new file mode 100644
index 000000000000..6adacb03c0d7
--- /dev/null
+++ b/arch/arm/mach-mx25/sdma_script_code.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008-2010 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_SENNA"
+
+************************************************************************/
+
+#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 233
+
+#define common_ADDR 313
+#define common_SIZE 416
+
+#define ap_2_ap_ADDR 729
+#define ap_2_ap_SIZE 41
+
+#define app_2_mcu_ADDR 770
+#define app_2_mcu_SIZE 64
+
+#define mcu_2_app_ADDR 834
+#define mcu_2_app_SIZE 70
+
+#define uart_2_mcu_ADDR 904
+#define uart_2_mcu_SIZE 75
+
+#define shp_2_mcu_ADDR 979
+#define shp_2_mcu_SIZE 69
+
+#define mcu_2_shp_ADDR 1048
+#define mcu_2_shp_SIZE 72
+
+#define uartsh_2_mcu_ADDR 1120
+#define uartsh_2_mcu_SIZE 69
+
+#define app_2_per_ADDR 1189
+#define app_2_per_SIZE 66
+
+#define per_2_app_ADDR 1255
+#define per_2_app_SIZE 74
+
+#define per_2_shp_ADDR 1329
+#define per_2_shp_SIZE 78
+
+#define shp_2_per_ADDR 1407
+#define shp_2_per_SIZE 72
+
+#define mcu_2_ata_ADDR 1479
+#define mcu_2_ata_SIZE 81
+
+#define ata_2_mcu_ADDR 1560
+#define ata_2_mcu_SIZE 96
+
+#define loop_DMAs_routines_ADDR 1656
+#define loop_DMAs_routines_SIZE 227
+
+#define test_ADDR 1883
+#define test_SIZE 63
+
+#define signature_ADDR 1022
+#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 uart_2_per_ADDR 6267
+#define uart_2_per_SIZE 73
+
+#define uartsh_2_per_ADDR 6340
+#define uartsh_2_per_SIZE 67
+
+/*!
+ * SDMA RAM image start address and size
+ */
+#define RAM_CODE_START_ADDR 6144
+#define RAM_CODE_SIZE 263
+
+/*!
+ * Buffer that holds the SDMA RAM image
+ */
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static const short sdma_code[] = {
+ 0x0e70, 0x0611, 0x5616, 0xc18a, 0x7d2a, 0x5ade, 0x008e, 0xc19c,
+ 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff,
+ 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5,
+ 0xd84f, 0x982b, 0x6b05, 0xc6d8, 0x7e27, 0x7f29, 0x982b, 0x6d01,
+ 0x03df, 0x7d05, 0x6bd5, 0xc702, 0x7e18, 0x7f1a, 0x982b, 0x6b05,
+ 0xc678, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc1a8, 0x7dd7, 0x0200,
+ 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc2ad,
+ 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, 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, 0x98c0, 0x6ee3, 0x008f, 0x2001, 0x00d5,
+ 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a,
+ 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d09, 0xc251,
+ 0x57db, 0x987f, 0x0007, 0x6aff, 0x62d0, 0xc2d1, 0x0458, 0x0454,
+ 0x6add, 0x7ff8, 0xc261, 0x987c, 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, 0x9903, 0x008f, 0x2001,
+ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d0e, 0x6ac8,
+ 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d0b,
+ 0xc251, 0x57db, 0x98c9, 0x0007, 0x6aff, 0x6add, 0x7ffc, 0x62d0,
+ 0xc2d1, 0x0458, 0x0454, 0x6add, 0x7ff6, 0xc261, 0x98c6
+};
+#endif
diff --git a/arch/arm/mach-mx25/serial.c b/arch/arm/mach-mx25/serial.c
new file mode 100644
index 000000000000..c2310d77c6b0
--- /dev/null
+++ b/arch/arm/mach-mx25/serial.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2008-2010 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-mx25/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX25
+ */
+#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-mx25_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 = {
+ .iotype = SERIAL_IO_MEM,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .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,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+ [1] = {
+ .port = {
+ .iotype = SERIAL_IO_MEM,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .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,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_IR_RXDMUX,
+ },
+#if UART3_ENABLED == 1
+ [2] = {
+ .port = {
+ .iotype = SERIAL_IO_MEM,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .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,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+#endif
+#if UART4_ENABLED == 1
+ [3] = {
+ .port = {
+ .iotype = SERIAL_IO_MEM,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 3,
+ },
+ .ints_muxed = UART4_MUX_INTS,
+ .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,
+ .dma_tx_id = MXC_DMA_UART4_TX,
+ .dma_rx_id = MXC_DMA_UART4_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+#endif
+#if UART5_ENABLED == 1
+ [4] = {
+ .port = {
+ .iotype = SERIAL_IO_MEM,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 4,
+ },
+ .ints_muxed = UART5_MUX_INTS,
+ .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,
+ .dma_tx_id = MXC_DMA_UART5_TX,
+ .dma_rx_id = MXC_DMA_UART5_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+#endif
+};
+
+static struct resource mxc_uart_resources1[] = {
+ {
+ .start = MX25_UART1_BASE_ADDR,
+ .end = MX25_UART1_BASE_ADDR + 0x0B5,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = UART1_INT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART1_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART1_INT3,
+ .flags = IORESOURCE_IRQ,
+ },
+
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_uart_resources1),
+ .resource = mxc_uart_resources1,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct resource mxc_uart_resources2[] = {
+ {
+ .start = MX25_UART2_BASE_ADDR,
+ .end = MX25_UART2_BASE_ADDR + 0x0B5,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = UART2_INT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART2_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART2_INT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mxc_uart_resources2),
+ .resource = mxc_uart_resources2,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+#if UART3_ENABLED == 1
+static struct resource mxc_uart_resources3[] = {
+ {
+ .start = MX25_UART3_BASE_ADDR,
+ .end = MX25_UART3_BASE_ADDR + 0x0B5,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = UART3_INT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART3_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART3_INT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(mxc_uart_resources3),
+ .resource = mxc_uart_resources3,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+#endif
+#if UART4_ENABLED == 1
+static struct resource mxc_uart_resources4[] = {
+ {
+ .start = MX25_UART4_BASE_ADDR,
+ .end = MX25_UART4_BASE_ADDR + 0x0B5,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = UART4_INT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART4_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART4_INT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_uart_device4 = {
+ .name = "mxcintuart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(mxc_uart_resources4),
+ .resource = mxc_uart_resources4,
+ .dev = {
+ .platform_data = &mxc_ports[3],
+ },
+};
+#endif
+#if UART5_ENABLED == 1
+static struct resource mxc_uart_resources5[] = {
+ {
+ .start = MX25_UART5_BASE_ADDR,
+ .end = MX25_UART5_BASE_ADDR + 0x0B5,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = UART5_INT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART5_INT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = UART5_INT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_uart_device5 = {
+ .name = "mxcintuart",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(mxc_uart_resources5),
+ .resource = mxc_uart_resources5,
+ .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);
+
+#if UART3_ENABLED == 1
+ 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-mx25/serial.h b/arch/arm/mach-mx25/serial.h
new file mode 100644
index 000000000000..c6e77f9159c2
--- /dev/null
+++ b/arch/arm/mach-mx25/serial.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008-2010 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_MX25_SERIAL_H__
+#define __ARCH_ARM_MACH_MX25_SERIAL_H__
+
+/*!
+ * @file mach-mx25/serial.h
+ *
+ * @ingroup MSL_MX25
+ */
+#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 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 1
+#define UART4_DMA_RXBUFSIZE 1024
+#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 1
+#define UART5_DMA_RXBUFSIZE 1024
+#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 MX25_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)
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MX25_INT_UART2
+#define UART2_INT2 (-1)
+#define UART2_INT3 (-1)
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MX25_INT_UART3
+#define UART3_INT2 (-1)
+#define UART3_INT3 (-1)
+/* UART 4 configuration */
+#define UART4_MUX_INTS INTS_MUXED
+#define UART4_INT1 MX25_INT_UART4
+#define UART4_INT2 (-1)
+#define UART4_INT3 (-1)
+/* UART 5 configuration */
+#define UART5_MUX_INTS INTS_MUXED
+#define UART5_INT1 MX25_INT_UART5
+#define UART5_INT2 (-1)
+#define UART5_INT3 (-1)
+
+#endif /* __ARCH_ARM_MACH_MX25_SERIAL_H__ */
diff --git a/arch/arm/mach-mx25/system.c b/arch/arm/mach-mx25/system.c
new file mode 100644
index 000000000000..f70b6017e61a
--- /dev/null
+++ b/arch/arm/mach-mx25/system.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008-2010 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/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include <mach/clock.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX25 i.MX25 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx25/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX25
+ */
+
+/*!
+ * MX25 low-power mode
+ */
+enum mx25_low_pwr_mode {
+ MX25_RUN_MODE,
+ MX25_WAIT_MODE,
+ MX25_DOZE_MODE,
+ MX25_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;
+ unsigned int pmcr1, pmcr2, lpimr;
+ unsigned int cgcr0, cgcr1, cgcr2;
+ struct irq_desc *desc;
+ int i;
+
+ /*read CCTL value */
+ reg = __raw_readl(MXC_CCM_CCTL);
+
+ switch (mode) {
+ case WAIT_UNCLOCKED_POWER_OFF:
+ lpm = MX25_DOZE_MODE;
+ break;
+
+ case STOP_POWER_ON:
+ case STOP_POWER_OFF:
+ lpm = MX25_STOP_MODE;
+ /* The clock of LCDC/SLCDC, SDMA, RTIC, RNGC, MAX, CAN
+ and EMI needs to be gated on when entering Stop mode.
+ */
+ cgcr0 = __raw_readl(MXC_CCM_CGCR0);
+ cgcr1 = __raw_readl(MXC_CCM_CGCR1);
+ cgcr2 = __raw_readl(MXC_CCM_CGCR2);
+ __raw_writel(cgcr0 | MXC_CCM_CGCR0_STOP_MODE_MASK,
+ MXC_CCM_CGCR0);
+ __raw_writel(cgcr1 | MXC_CCM_CGCR1_STOP_MODE_MASK,
+ MXC_CCM_CGCR1);
+ __raw_writel(cgcr2 | MXC_CCM_CGCR2_STOP_MODE_MASK,
+ MXC_CCM_CGCR2);
+ /* The interrupts which are not wake-up sources need
+ be mask when entering Stop mode.
+ */
+ lpimr = MXC_CCM_LPIMR0_MASK;
+ for (i = 0; i < 32; i++) {
+ desc = irq_desc + i;
+ if ((desc->status & IRQ_WAKEUP) != 0)
+ lpimr &= ~(1 << i);
+ }
+ __raw_writel(lpimr, MXC_CCM_LPIMR0);
+ lpimr = MXC_CCM_LPIMR1_MASK;
+ for (i = 32; i < 64; i++) {
+ desc = irq_desc + i;
+ if ((desc->status & IRQ_WAKEUP) != 0)
+ lpimr &= ~(1 << (i - 32));
+ }
+ __raw_writel(lpimr, MXC_CCM_LPIMR1);
+
+ if (mode == STOP_POWER_OFF) {
+ pmcr2 = __raw_readl(MXC_CCM_PMCR2);
+ pmcr2 |= (MXC_CCM_PMCR2_OSC24M_DOWN |
+ MXC_CCM_PMCR2_VSTBY);
+ __raw_writel(pmcr2, MXC_CCM_PMCR2);
+ pmcr1 = __raw_readl(MXC_CCM_PMCR1);
+ pmcr1 &= ~(MXC_CCM_PMCR1_WBCN_MASK |
+ MXC_CCM_PMCR1_CSPAEM_MASK |
+ MXC_CCM_PMCR1_CSPA_MASK);
+ pmcr1 |= MXC_CCM_PMCR1_AWB_DEFAULT;
+ __raw_writel(pmcr1, MXC_CCM_PMCR1);
+ }
+ break;
+
+ case WAIT_CLOCKED:
+ case WAIT_UNCLOCKED:
+ default:
+ /* Wait is the default mode used when idle. */
+ lpm = MX25_WAIT_MODE;
+ break;
+ }
+
+ /* program LP CTL bit */
+ reg = ((reg & (~MXC_CCM_CCTL_LP_CTL_MASK)) |
+ lpm << MXC_CCM_CCTL_LP_CTL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CCTL);
+}
+
+/*!
+ * 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) {
+ /* set as Wait mode */
+ mxc_cpu_lp_set(WAIT_UNCLOCKED);
+ cpu_do_idle();
+ }
+}
+
+#if 0
+/*
+ * 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();
+}
+#endif
diff --git a/arch/arm/mach-mx25/usb.h b/arch/arm/mach-mx25/usb.h
new file mode 100644
index 000000000000..b1c21a7ffaa8
--- /dev/null
+++ b/arch/arm/mach-mx25/usb.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2005-2010 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_utmi_active(void);
+extern void gpio_usbotg_utmi_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_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.
+ */
+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-mx25/usb_dr.c b/arch/arm/mach-mx25/usb_dr.c
new file mode 100644
index 000000000000..9dd6c8f54911
--- /dev/null
+++ b/arch/arm/mach-mx25/usb_dr.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2005-2010 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/hardware.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable);
+
+/*
+ * 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, /* via RT9706 */
+ .gpio_usb_active = gpio_usbotg_utmi_active,
+ .gpio_usb_inactive = gpio_usbotg_utmi_inactive,
+ .transceiver = "utmi",
+ .wake_up_enable = _wake_up_enable,
+};
+
+/*
+ * OTG resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(USB_OTGREGS_BASE),
+ .end = (u32)(USB_OTGREGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MX25_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * UDC resources (same as OTG resource)
+ */
+static struct resource udc_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 = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_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 void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ if (get_usb_mode(pdata) == FSL_USB_DR_DEVICE) {
+ if (enable)
+ USBCTRL |= (UCTRL_OWIE | UCTRL_VBUS_WKUP_EN);
+ else {
+ USBCTRL &= ~UCTRL_OWIE;
+ USBCTRL &= ~UCTRL_VBUS_WKUP_EN;
+ }
+ } else {
+ if (enable)
+ USBCTRL |= UCTRL_OWIE;
+ else
+ USBCTRL &= ~UCTRL_OWIE;
+ }
+}
+
+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-mx25/usb_h2.c b/arch/arm/mach-mx25/usb_h2.c
new file mode 100644
index 000000000000..ba29172df3a8
--- /dev/null
+++ b/arch/arm/mach-mx25/usb_h2.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005-2010 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/consumer.h>
+#include <mach/hardware.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, /* via RT9702 */
+ .gpio_usb_active = gpio_usbh2_active,
+ .gpio_usb_inactive = gpio_usbh2_inactive,
+ .transceiver = "serial", /* on-chip */
+};
+
+static struct resource usbh2_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H2REGS_BASE),
+ .end = (u32) (USB_H2REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MX25_INT_USB_HTG,
+ .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);
+
+ usbh2_regux = ((struct fsl_usb2_platform_data *)dev->
+ platform_data)->xcvr_pwr->regu1;
+ regulator_disable(usbh2_regux);
+ regulator_put(usbh2_regux);
+}
+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);