diff options
author | Rob Herring <r.herring@freescale.com> | 2009-10-19 14:43:19 -0500 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-02-12 17:19:16 +0100 |
commit | cdde68e3a7d4cbf4701005ab6032366e76009419 (patch) | |
tree | 5690552665f0b7843e6552e4d5fe7b63cbc78f51 /arch/arm/mach-mx3 | |
parent | 57d1417ea543b83760b3fd76a46b9d29deb2e444 (diff) |
ENGR00117389 Port 5.0.0 release to 2.6.31
This is i.MX BSP 5.0.0 release ported to 2.6.31
Signed-off-by: Rob Herring <r.herring@freescale.com>
Signed-off-by: Alan Tull <r80115@freescale.com>
Signed-off-by: Xinyu Chen <xinyu.chen@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx3')
31 files changed, 12492 insertions, 764 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 851f2458bf65..5aaae399cc73 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -4,9 +4,17 @@ config ARCH_MX31 select ARCH_HAS_RNGA bool -config ARCH_MX35 +config MX3_OPTIONS bool - select ARCH_MXC_IOMUX_V3 + default y + select CPU_V6 + select ARM_ERRATA_364296 + select ARM_ERRATA_411920 + select CACHE_L2X0 + select OUTER_CACHE + select USB_ARCH_HAS_EHCI + select ARCH_HAS_EVTMON + select ARCH_HAS_RNGA comment "MX3 platforms:" @@ -81,7 +89,7 @@ config MACH_QONG config MACH_PCM043 bool "Support Phytec pcm043 (i.MX35) platforms" - select ARCH_MX35 +# select ARCH_MX35 help Include support for Phytec pcm043 platform. This includes specific configurations for the board and its peripherals. @@ -92,12 +100,72 @@ config MACH_ARMADILLO5X0 help Include support for Atmark Armadillo-500 platform. This includes specific configurations for the board and its peripherals. + Include support for Phytec pcm043 platform. This includes + specific configurations for the board and its peripherals. + +config MXC_SDMA_API + bool "Use SDMA API" + default y + help + This selects the Freescale MXC SDMA API. + If unsure, say N. + +menu "SDMA options" + depends on MXC_SDMA_API + +config SDMA_IRAM + bool "Use Internal RAM for SDMA transfer" + default n + help + Support Internal RAM as SDMA buffer or control structures + +config SDMA_IRAM_SIZE + hex "Reserved bytes of IRAM for SDMA (0x800-0x2000)" + range 0x800 0x2000 + depends on SDMA_IRAM + default "0x1000" + help + Set the size of IRAM for SDMA. It must be multiple of 512bytes. +endmenu + +config ARCH_MXC_HAS_NFC_V1 + bool "MXC NFC Hardware Version 1" + depends on !(MACH_MX31ADS && XIP_KERNEL) + default y + help + This selects the Freescale MXC Nand Flash Controller Hardware Version 1 + If unsure, say N. -config MACH_MX35_3DS - bool "Support MX35PDK platform" - select ARCH_MX35 +config ARCH_MXC_HAS_NFC_V2 + bool "MXC NFC Hardware Version 2" + depends on !(MACH_MX31ADS && XIP_KERNEL) + default y + help + This selects the Freescale MXC Nand Flash Controller Hardware Version 2 + If unsure, say N. + +menu "Device options" + +config I2C_MXC_SELECT1 + bool "Enable I2C1 module" + default y + depends on I2C_MXC + help + Enable MX31 I2C1 module. + +config I2C_MXC_SELECT2 + bool "Enable I2C2 module" default n + depends on I2C_MXC help - Include support for MX35PDK platform. This includes specific - configurations for the board and its peripherals. + Enable MX31 I2C2 module. + +config I2C_MXC_SELECT3 + bool "Enable I2C3 module" + default n + depends on I2C_MXC + help + Enable MX31 I2C3 module. + +endmenu endif diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 6b9775471be6..ddbbf2672309 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -4,18 +4,25 @@ # Object file lists. -obj-y := mm.o devices.o -obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o -obj-$(CONFIG_ARCH_MX35) += clock-imx35.o -obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o +obj-y := system.o iomux.o cpu.o mm.o clock.o dptc.o devices.o serial.o dma.o mxc_pm.o dvfs_v2.o +obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o mx31ads_gpio.o obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o obj-$(CONFIG_MACH_PCM037_EET) += pcm037_eet.o -obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o +obj-$(CONFIG_MACH_MX31_3DS) += mx3_3stack.o mx3_3stack_gpio.o mx3_3stack_pmic_mc13783.o obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ mx31moboard-marxbot.o obj-$(CONFIG_MACH_QONG) += qong.o obj-$(CONFIG_MACH_PCM043) += pcm043.o obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o -obj-$(CONFIG_MACH_MX35_3DS) += mx35pdk.o + +# power management +obj-$(CONFIG_PM) += pm.o + +obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o +obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o + +ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),) + obj-y += usb_dr.o +endif diff --git a/arch/arm/mach-mx3/board-mx31ads.h b/arch/arm/mach-mx3/board-mx31ads.h new file mode 100644 index 000000000000..658e3e736c0f --- /dev/null +++ b/arch/arm/mach-mx3/board-mx31ads.h @@ -0,0 +1,329 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ +#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ + +#ifdef CONFIG_MACH_MX31ADS +/*! + * @defgroup BRDCFG_MX31 Board Configuration Options + * @ingroup MSL_MX31 + */ + +/*! + * @file mach-mx3/board-mx31ads.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for MX31 ADS Platform. + * + * @ingroup BRDCFG_MX31 + */ + +/* + * Include Files + */ +#include <mach/mxc_uart.h> + +/*! + * @name MXC UART EVB board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 + +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR IRDA +#ifdef CONFIG_MXC_FIR_MODULE +#define UART2_ENABLED 0 +#else +#define UART2_ENABLED 1 +#endif +/* UART 3 configuration */ +#define UART3_MODE MODE_DTE +#define UART3_IR NO_IRDA +#define UART3_ENABLED 1 +/* UART 4 configuration */ +#define UART4_MODE MODE_DTE +#define UART4_IR NO_IRDA +#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */ +/* UART 5 configuration */ +#define UART5_MODE MODE_DTE +#define UART5_IR NO_IRDA +#define UART5_ENABLED 1 + +#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x10000) +#define MXC_LL_EXTUART_VADDR CS4_IO_ADDRESS(MXC_LL_EXTUART_PADDR) +#undef MXC_LL_EXTUART_16BIT_BUS + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +/*! + * @name PBC Controller parameters + */ +/*! @{ */ +/*! + * Base address of PBC controller + */ +#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR) +/* Offsets for the PBC Controller register */ +/*! + * PBC Board status register offset + */ +#define PBC_BSTAT 0x000002 +/*! + * PBC Board control register 1 set address. + */ +#define PBC_BCTRL1_SET 0x000004 +/*! + * PBC Board control register 1 clear address. + */ +#define PBC_BCTRL1_CLEAR 0x000006 +/*! + * PBC Board control register 2 set address. + */ +#define PBC_BCTRL2_SET 0x000008 +/*! + * PBC Board control register 2 clear address. + */ +#define PBC_BCTRL2_CLEAR 0x00000A +/*! + * PBC Board control register 3 set address. + */ +#define PBC_BCTRL3_SET 0x00000C +/*! + * PBC Board control register 3 clear address. + */ +#define PBC_BCTRL3_CLEAR 0x00000E +/*! + * PBC Board control register 4 set address. + */ +#define PBC_BCTRL4_SET 0x000010 +/*! + * PBC Board control register 4 clear address. + */ +#define PBC_BCTRL4_CLEAR 0x000012 +/*! + * PBC Board status register 1. + */ +#define PBC_BSTAT1 0x000014 +/*! + * PBC Board interrupt status register. + */ +#define PBC_INTSTATUS 0x000016 +/*! + * PBC Board interrupt current status register. + */ +#define PBC_INTCURR_STATUS 0x000018 +/*! + * PBC Interrupt mask register set address. + */ +#define PBC_INTMASK_SET 0x00001A +/*! + * PBC Interrupt mask register clear address. + */ +#define PBC_INTMASK_CLEAR 0x00001C + +/*! + * External UART A. + */ +#define PBC_SC16C652_UARTA 0x010000 +/*! + * External UART B. + */ +#define PBC_SC16C652_UARTB 0x010010 +/*! + * Ethernet Controller IO base address. + */ +#define PBC_CS8900A_IOBASE 0x020000 +/*! + * Ethernet Controller Memory base address. + */ +#define PBC_CS8900A_MEMBASE 0x021000 +/*! + * Ethernet Controller DMA base address. + */ +#define PBC_CS8900A_DMABASE 0x022000 +/*! + * External chip select 0. + */ +#define PBC_XCS0 0x040000 +/*! + * LCD Display enable. + */ +#define PBC_LCD_EN_B 0x060000 +/*! + * Code test debug enable. + */ +#define PBC_CODE_B 0x070000 +/*! + * PSRAM memory select. + */ +#define PBC_PSRAM_B 0x5000000 + +/* PBC Board Status Register 1 bit definitions */ +#define PBC_BSTAT1_NF_DET 0x0001 /* NAND flash card. 0 = connected */ +#define PBC_BSTAT1_KP_ON 0x0002 /* KPP board. 0 = connected */ +#define PBC_BSTAT1_LS 0x0004 /* KPP:LightSense signal */ +#define PBC_BSTAT1_ATA_IOCS16 0x0008 /* ATA_IOCS16 signal */ +#define PBC_BSTAT1_ATA_CBLID 0x0010 /* ATA_CBLID signal */ +#define PBC_BSTAT1_ATA_DASP 0x0020 /* ATA_DASP signal */ +#define PBC_BSTAT1_PWR_RDY 0x0040 /* MC13783 power. 1 = ready */ +#define PBC_BSTAT1_SD1_WP 0x0080 /* 0 = SD1 card is write protected */ +#define PBC_BSTAT1_SD2_WP 0x0100 /* 0 = SD2 card is write protected */ +#define PBC_BSTAT1_FS1 0x0200 /* KPP:FlipSense1 signal */ +#define PBC_BSTAT1_FS2 0x0400 /* KPP:FlipSense2 signal */ +#define PBC_BSTAT1_PTT 0x0800 /* KPP:PTT signal */ +#define PBC_BSTAT1_MC13783_IN 0x1000 /* MC13783 board. 0 = connected. */ + +/* PBC Board Control Register 1 bit definitions */ +#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */ +#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */ +#define PBC_BCTRL1_UENA 0x0004 /* Enable UART A transceiver */ +#define PBC_BCTRL1_UENB 0x0008 /* Enable UART B transceiver */ +#define PBC_BCTRL1_UENCE 0x0010 /* Enable UART CE transceiver */ +#define PBC_BCTRL1_IREN 0x0020 /* Enable the IRDA transmitter */ +#define PBC_BCTRL1_LED0 0x0040 /* Used to control LED 0 (green) */ +#define PBC_BCTRL1_LED1 0x0080 /* Used to control LED 1 (yellow) */ +#define PBC_BCTRL1_SENSOR1_ON 0x0600 /* Enable Sensor 1 */ +#define PBC_BCTRL1_SENSOR2_ON 0x3000 /* Enable Sensor 2 */ +#define PBC_BCTRL1_BEND 0x4000 /* Big Endian Select */ +#define PBC_BCTRL1_LCDON 0x8000 /* Enable the LCD */ + +/* PBC Board Control Register 2 bit definitions */ +#define PBC_BCTRL2_USELA 0x0001 /* UART A Select, 0 = UART1, 1 = UART5 */ +#define PBC_BCTRL2_USELB 0x0002 /* UART B Select, 0 = UART3, 1 = UART5 */ +#define PBC_BCTRL2_USELC 0x0004 /* UART C Select, 0 = UART2, 1 = UART1 */ +#define PBC_BCTRL2_UMODENA 0x0008 /* UART A Modem Signals Enable, 0 = enabled */ +#define PBC_BCTRL2_UMODENC 0x0008 /* UART C Modem Signals Enable, 0 = enabled */ +#define PBC_BCTRL2_CSI_EN 0x0020 /* Enable the CSI interface, 0 = enabled */ +#define PBC_BCTRL2_ATA_EN 0x0040 /* Enable the ATA interface, 0 = enabled */ +#define PBC_BCTRL2_ATA_SEL 0x0080 /* ATA Select, 0 = group A, 1 = group B */ +#define PBC_BCTRL2_IRDA_MOD 0x0100 /* IRDA Mode (see CPLD spec) */ +#define PBC_BCTRL2_LDC_RST0 0x0200 /* LCD 0 Reset, 1 = reset signal asserted */ +#define PBC_BCTRL2_LDC_RST1 0x0400 /* LCD 1 Reset, 1 = reset signal asserted */ +#define PBC_BCTRL2_LDC_RST2 0x0800 /* LCD 2 Reset, 1 = reset signal asserted */ +#define PBC_BCTRL2_LDCIO_EN 0x1000 /* LCD GPIO Enable, 0 = enabled */ +#define PBC_BCTRL2_CT_CS 0x2000 /* Code Test Chip Select, = Code Test selected */ +#define PBC_BCTRL2_VPP_EN 0x4000 /* PCMCIA VPP Enable, 1 = power on */ +#define PBC_BCTRL2_VCC_EN 0x8000 /* PCMCIA VCC Enable, 1 = power on */ + +/* PBC Board Control Register 3 bit definitions */ +#define PBC_BCTRL3_OTG_FS_SEL 0x0001 /* USB OTG Full Speed Select, 0 = PMIC, 1 = CPU */ +#define PBC_BCTRL3_OTG_FS_EN 0x0002 /* USB OTG Full Speed Enable, 0 = enabled */ +#define PBC_BCTRL3_FSH_SEL 0x0004 /* USB Full Speed Host Select, 0 = Group A, 1 = Group B */ +#define PBC_BCTRL3_FSH_EN 0x0008 /* USB Full Speed Host Enable, 0 = enabled */ +#define PBC_BCTRL3_HSH_SEL 0x0010 /* USB High Speed Host Select, 0 = Group A, 1 = Group B */ +#define PBC_BCTRL3_HSH_EN 0x0020 /* USB High Speed Host Enable, 0 = enabled */ +#define PBC_BCTRL3_FSH_MOD 0x0040 /* USB Full Speed Host Mode, 0 = Differential, 1 = Single ended */ +#define PBC_BCTRL3_OTG_HS_EN 0x0080 /* USB OTG High Speed Enable, 0 = enabled */ +#define PBC_BCTRL3_OTG_VBUS_EN 0x0100 /* USB OTG VBUS Regulator Enable, 0 = enabled */ +#define PBC_BCTRL3_FSH_VBUS_EN 0x0200 /* USB Full Speed Host VBUS Regulator Enable, 0 = enabled */ +#define PBC_BCTRL3_CARD1_SEL 0x0400 /* Card1 Select, 0 = SD1, 1 = MS1 */ +#define PBC_BCTRL3_CARD2_SEL 0x0800 /* Card2 Select, 0 = PCMCIA & SD2, 1 = MS2 */ +#define PBC_BCTRL3_SYNTH_RST 0x1000 /* Audio Synthesizer Reset, 0 = reset asserted */ +#define PBC_BCTRL3_VSIM_EN 0x2000 /* VSIM Regulator Enable, 1 = enabled */ +#define PBC_BCTRL3_VESIM_EN 0x4000 /* VESIM Regulator Enable, 1 = enabled */ +#define PBC_BCTRL3_SPI3_RESET 0x8000 /* CSPI3 Connector Reset, 0 = reset asserted */ + +/* PBC Board Control Register 4 bit definitions */ +#define PBC_BCTRL4_CSI_MSB_EN 0x0001 /* CSI MSB Enable, 0 = CSI_Data[3:0] enabled */ +#define PBC_BCTRL4_REGEN_SEL 0x0002 /* Regulator Enable Select, 0 = enabled */ +#define PBC_BCTRL4_USER_OFF 0x0004 /* User Off Indication, 1 = user off confirmation */ +#define PBC_BCTRL4_VIB_EN 0x0008 /* Vibrator Enable, 1 = enabled */ +#define PBC_BCTRL4_PCMCIA_EN 0x0010 /* PCMCIA Enable, 0 = buffer enabled */ + +#define CKIH_27MHZ_BIT_SET (1 << 4) + +#define PBC_INT_CS8900A 4 +/*! @} */ + +#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS) +#define PBC_INTCURR_STATUS_REG (PBC_INTCURR_STATUS + PBC_BASE_ADDRESS) +#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS) +#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) + +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) +#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 0) +#define EXPIO_INT_PB_IRQ (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4) +#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5) +#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6) +#define EXPIO_INT_RES7 (MXC_EXP_IO_BASE + 7) +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9) +#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) +#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11) +#define EXPIO_INT_SYNTH_IRQ (MXC_EXP_IO_BASE + 12) +#define EXPIO_INT_CE_INT1 (MXC_EXP_IO_BASE + 13) +#define EXPIO_INT_CE_INT2 (MXC_EXP_IO_BASE + 14) +#define EXPIO_INT_RES15 (MXC_EXP_IO_BASE + 15) + +#define MXC_MAX_EXP_IO_LINES 16 + +/*! + * @name Defines Base address and IRQ used for CS8900A Ethernet Controller on MXC Boards + */ +/*! @{*/ +/*! This is System IRQ used by CS8900A for interrupt generation taken from platform.h */ +#define CS8900AIRQ EXPIO_INT_ENET_INT +/*! This is I/O Base address used to access registers of CS8900A on MXC ADS */ +#define CS8900A_BASE_ADDRESS (PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300) +/*! @} */ + +#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX31_PIN_GPIO1_3) + +#define AHB_FREQ 133000000 +#define IPG_FREQ 66500000 + +#define MXC_BD_LED1 (1 << 6) +#define MXC_BD_LED2 (1 << 7) +#define MXC_BD_LED_ON(led) \ + __raw_writew(led, PBC_BASE_ADDRESS + PBC_BCTRL1_SET) +#define MXC_BD_LED_OFF(led) \ + __raw_writew(led, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR) + +#endif /* CONFIG_MACH_MX31ADS */ +#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/arch/arm/mach-mx3/board-mx3_3stack.h b/arch/arm/mach-mx3/board-mx3_3stack.h new file mode 100644 index 000000000000..fd58060c9a18 --- /dev/null +++ b/arch/arm/mach-mx3/board-mx3_3stack.h @@ -0,0 +1,153 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ +#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ + +#ifdef CONFIG_MACH_MX31_3DS +/*! + * @defgroup BRDCFG_MX31 Board Configuration Options + * @ingroup MSL_MX31 + */ + +/*! + * @file mach-mx3/board-mx3_3stack.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for MX31 3STACK Platform. + * + * @ingroup BRDCFG_MX31 + */ + +/* + * Include Files + */ +#include <mach/mxc_uart.h> + +/*! + * @name MXC UART EVB board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 + +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR NO_IRDA +#define UART2_ENABLED 1 +/* UART 3 configuration */ +#define UART3_MODE MODE_DTE +#define UART3_IR NO_IRDA +#define UART3_ENABLED 1 +/* UART 4 configuration */ +#define UART4_MODE MODE_DTE +#define UART4_IR NO_IRDA +#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */ +/* UART 5 configuration */ +#define UART5_MODE MODE_DTE +#define UART5_IR NO_IRDA +#define UART5_ENABLED 0 + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#define DEBUG_BASE_ADDRESS CS5_BASE_ADDR +/* LAN9217 ethernet base address */ +#define LAN9217_BASE_ADDR DEBUG_BASE_ADDRESS +/* External UART */ +#define UARTA_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x8000) +#define UARTB_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x10000) + +#define BOARD_IO_ADDR (DEBUG_BASE_ADDRESS + 0x20000) +/* LED switchs */ +#define LED_SWITCH_REG 0x00 +/* buttons */ +#define SWITCH_BUTTONS_REG 0x08 +/* status, interrupt */ +#define INTR_STATUS_REG 0x10 +#define INTR_MASK_REG 0x38 +#define INTR_RESET_REG 0x20 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER1_REG 0x40 +#define MAGIC_NUMBER2_REG 0x48 +/* CPLD code version */ +#define CPLD_CODE_VER_REG 0x50 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER3_REG 0x58 +/* module reset register*/ +#define MODULE_RESET_REG 0x60 +/* CPU ID and Personality ID */ +#define MCU_BOARD_ID_REG 0x68 + +/* interrupts like external uart , external ethernet etc*/ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) + +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) +#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) +#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) +#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) +#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) +#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) + +/*! This is System IRQ used by LAN9217 */ +#define LAN9217_IRQ EXPIO_INT_ENET + +/*! LED definition*/ +#define MXC_BD_LED1 (1) +#define MXC_BD_LED2 (1 << 1) +#define MXC_BD_LED3 (1 << 2) +#define MXC_BD_LED4 (1 << 3) +#define MXC_BD_LED5 (1 << 4) +#define MXC_BD_LED6 (1 << 5) +#define MXC_BD_LED7 (1 << 6) +#define MXC_BD_LED8 (1 << 7) + +#define MXC_BD_LED_ON(led) +#define MXC_BD_LED_OFF(led) + +extern unsigned int sdhc_get_card_det_status(struct device *dev); +extern int sdhc_init_card_det(int id); +extern int sdhc_write_protect(struct device *dev); + +extern int __init mx3_3stack_init_mc13783(void); + +#endif /* CONFIG_MACH_MX31_3DS */ +#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */ diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 8b14239724c9..bf19312acb1a 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> * * This program is free software; you can redistribute it and/or @@ -17,23 +17,27 @@ * MA 02110-1301, USA. */ +#include <linux/kernel.h> #include <linux/module.h> #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> - -#include <asm/clkdev.h> -#include <asm/div64.h> - #include <mach/clock.h> #include <mach/hardware.h> +#include <mach/mxc_dptc.h> +#include <asm/div64.h> #include <mach/common.h> +#include <mach/mxc_dptc.h> #include "crm_regs.h" #define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ +#define PROPAGATE_RATE_DIS 2 + +static int cpu_clk_set_wp(int wp); +struct timer_list dptcen_timer; static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) { @@ -68,17 +72,17 @@ static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) } static struct clk mcu_pll_clk; +static struct clk mcu_main_clk; +static struct clk usb_pll_clk; static struct clk serial_pll_clk; static struct clk ipg_clk; static struct clk ckih_clk; +static struct clk ahb_clk; -static int cgr_enable(struct clk *clk) +static int _clk_enable(struct clk *clk) { u32 reg; - if (!clk->enable_reg) - return 0; - reg = __raw_readl(clk->enable_reg); reg |= 3 << clk->enable_shift; __raw_writel(reg, clk->enable_reg); @@ -86,69 +90,150 @@ static int cgr_enable(struct clk *clk) return 0; } -static void cgr_disable(struct clk *clk) +static void _clk_disable(struct clk *clk) { u32 reg; - if (!clk->enable_reg) - return; - reg = __raw_readl(clk->enable_reg); reg &= ~(3 << clk->enable_shift); - - /* special case for EMI clock */ - if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) - reg |= (1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); } -static unsigned long pll_ref_get_rate(void) +static void _clk_emi_disable(struct clk *clk) { - unsigned long ccmr; - unsigned int prcs; + u32 reg; - ccmr = __raw_readl(MXC_CCM_CCMR); - prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; - if (prcs == 0x1) - return CKIL_CLK_FREQ * 1024; - else - return clk_get_rate(&ckih_clk); + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + reg |= (1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); } -static unsigned long usb_pll_get_rate(struct clk *clk) +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) { - unsigned long reg; + u32 reg; + signed long pd = 1; /* Pre-divider */ + signed long mfi; /* Multiplication Factor (Integer part) */ + signed long mfn; /* Multiplication Factor (Integer part) */ + signed long mfd; /* Multiplication Factor (Denominator Part) */ + signed long tmp; + u32 ref_freq = clk_get_rate(clk->parent); + + while (((ref_freq / pd) * 10) > rate) + pd++; + + if ((ref_freq / pd) < PRE_DIV_MIN_FREQ) + return -EINVAL; + + /* the ref_freq/2 in the following is to round up */ + mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; + if (mfi < 5 || mfi > 15) + return -EINVAL; - reg = __raw_readl(MXC_CCM_UPCTL); + /* pick a mfd value that will work + * then solve for mfn */ + mfd = ref_freq / 50000; - return mxc_decode_pll(reg, pll_ref_get_rate()); + /* + * pll_freq * pd * mfd + * mfn = -------------------- - (mfi * mfd) + * 2 * ref_freq + */ + /* the tmp/2 is for rounding */ + tmp = ref_freq / 10000; + mfn = + ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - + (mfi * mfd); + + mfn = mfn & 0x3ff; + pd--; + mfd--; + + /* Change the Pll value */ + reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) | + (mfn << MXC_CCM_PCTL_MFN_OFFSET) | + (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET); + + if (clk == &mcu_pll_clk) + __raw_writel(reg, MXC_CCM_MPCTL); + else if (clk == &usb_pll_clk) + __raw_writel(reg, MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + __raw_writel(reg, MXC_CCM_SRPCTL); + + clk->rate = rate; + return 0; } -static unsigned long serial_pll_get_rate(struct clk *clk) +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) { - unsigned long reg; + if ((rate < ahb_clk.rate) || (rate % ahb_clk.rate != 0)) { + printk(KERN_ERR "Wrong rate %lu in _clk_cpu_set_rate\n", rate); + return -EINVAL; + } - reg = __raw_readl(MXC_CCM_SRPCTL); + cpu_clk_set_wp(rate / ahb_clk.rate - 1); - return mxc_decode_pll(reg, pll_ref_get_rate()); + return PROPAGATE_RATE_DIS; } -static unsigned long mcu_pll_get_rate(struct clk *clk) +static void _clk_pll_recalc(struct clk *clk) { + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; unsigned long reg, ccmr; + s64 temp; + unsigned int prcs; ccmr = __raw_readl(MXC_CCM_CCMR); + prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; + if (prcs == 0x1) + ref_clk = CKIL_CLK_FREQ * 1024; + else + ref_clk = clk_get_rate(&ckih_clk); + + if (clk == &mcu_pll_clk) { + if ((ccmr & MXC_CCM_CCMR_MPE) == 0) { + clk->rate = ref_clk; + return; + } + if ((ccmr & MXC_CCM_CCMR_MDS) != 0) { + clk->rate = ref_clk; + return; + } + reg = __raw_readl(MXC_CCM_MPCTL); + } else if (clk == &usb_pll_clk) + reg = __raw_readl(MXC_CCM_UPCTL); + else if (clk == &serial_pll_clk) + reg = __raw_readl(MXC_CCM_SRPCTL); + else { + BUG(); + return; + } + + pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET; + mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET; + mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK; - if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) - return clk_get_rate(&ckih_clk); + if (mfn >= 0x200) { + mfn |= 0xFFFFFE00; + mfn_abs = -mfn; + } + + ref_clk *= 2; + ref_clk /= pdf + 1; - reg = __raw_readl(MXC_CCM_MPCTL); + temp = (u64) ref_clk * mfn_abs; + do_div(temp, mfd + 1); + if (mfn < 0) + temp = -temp; + temp = (ref_clk * mfi) + temp; - return mxc_decode_pll(reg, pll_ref_get_rate()); + clk->rate = temp; } -static int usb_pll_enable(struct clk *clk) +static int _clk_usb_pll_enable(struct clk *clk) { u32 reg; @@ -162,7 +247,7 @@ static int usb_pll_enable(struct clk *clk) return 0; } -static void usb_pll_disable(struct clk *clk) +static void _clk_usb_pll_disable(struct clk *clk) { u32 reg; @@ -171,7 +256,7 @@ static void usb_pll_disable(struct clk *clk) __raw_writel(reg, MXC_CCM_CCMR); } -static int serial_pll_enable(struct clk *clk) +static int _clk_serial_pll_enable(struct clk *clk) { u32 reg; @@ -185,7 +270,7 @@ static int serial_pll_enable(struct clk *clk) return 0; } -static void serial_pll_disable(struct clk *clk) +static void _clk_serial_pll_disable(struct clk *clk) { u32 reg; @@ -198,53 +283,103 @@ static void serial_pll_disable(struct clk *clk) #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) -static unsigned long mcu_main_get_rate(struct clk *clk) +static void _clk_mcu_main_recalc(struct clk *clk) { u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); - if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) - return clk_get_rate(&serial_pll_clk); - else - return clk_get_rate(&mcu_pll_clk); + if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) { + serial_pll_clk.recalc(&serial_pll_clk); + clk->rate = serial_pll_clk.rate; + } else { + mcu_pll_clk.recalc(&mcu_pll_clk); + clk->rate = mcu_pll_clk.rate; + } +} + +static void _clk_cpu_recalc(struct clk *clk) +{ + unsigned long mcu_pdf; + + mcu_pdf = PDR0(MXC_CCM_PDR0_MCU_PODF_MASK, + MXC_CCM_PDR0_MCU_PODF_OFFSET); + clk->rate = clk->parent->rate / (mcu_pdf + 1); } -static unsigned long ahb_get_rate(struct clk *clk) +static void _clk_hclk_recalc(struct clk *clk) { unsigned long max_pdf; max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK, MXC_CCM_PDR0_MAX_PODF_OFFSET); - return clk_get_rate(clk->parent) / (max_pdf + 1); + clk->rate = clk->parent->rate / (max_pdf + 1); } -static unsigned long ipg_get_rate(struct clk *clk) +static void _clk_ipg_recalc(struct clk *clk) { unsigned long ipg_pdf; ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK, MXC_CCM_PDR0_IPG_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ipg_pdf + 1); + clk->rate = clk->parent->rate / (ipg_pdf + 1); } -static unsigned long nfc_get_rate(struct clk *clk) +static void _clk_nfc_recalc(struct clk *clk) { unsigned long nfc_pdf; nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK, MXC_CCM_PDR0_NFC_PODF_OFFSET); - return clk_get_rate(clk->parent) / (nfc_pdf + 1); + clk->rate = clk->parent->rate / (nfc_pdf + 1); + +} + +static int _clk_nfc_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + + div = clk->parent->rate / rate; + + if ((clk->parent->rate / div) != rate) + return -EINVAL; + + if (div > 8) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_PDR0) & ~MXC_CCM_PDR0_NFC_PODF_MASK; + reg |= (div - 1) << MXC_CCM_PDR0_NFC_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_PDR0); + + clk->rate = rate; + + return 0; + } -static unsigned long hsp_get_rate(struct clk *clk) +static unsigned long _clk_nfc_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div = clk->parent->rate / rate; + + if (clk->parent->rate % rate) + div++; + + if (div > 8) + return -EINVAL; + + return clk->parent->rate / div; + +} + +static void _clk_hsp_recalc(struct clk *clk) { unsigned long hsp_pdf; hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK, MXC_CCM_PDR0_HSP_PODF_OFFSET); - return clk_get_rate(clk->parent) / (hsp_pdf + 1); + clk->rate = clk->parent->rate / (hsp_pdf + 1); } -static unsigned long usb_get_rate(struct clk *clk) +static void _clk_usb_recalc(struct clk *clk) { unsigned long usb_pdf, usb_prepdf; @@ -252,10 +387,10 @@ static unsigned long usb_get_rate(struct clk *clk) MXC_CCM_PDR1_USB_PODF_OFFSET); usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK, MXC_CCM_PDR1_USB_PRDF_OFFSET); - return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); + clk->rate = clk->parent->rate / (usb_prepdf + 1) / (usb_pdf + 1); } -static unsigned long csi_get_rate(struct clk *clk) +static void _clk_csi_recalc(struct clk *clk) { u32 reg, pre, post; @@ -266,10 +401,10 @@ static unsigned long csi_get_rate(struct clk *clk) post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >> MXC_CCM_PDR0_CSI_PODF_OFFSET; post++; - return clk_get_rate(clk->parent) / (pre * post); + clk->rate = clk->parent->rate / (pre * post); } -static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) +static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) { u32 pre, post, parent = clk_get_rate(clk->parent); u32 div = parent / rate; @@ -282,7 +417,7 @@ static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) return parent / (pre * post); } -static int csi_set_rate(struct clk *clk, unsigned long rate) +static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) { u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); @@ -300,10 +435,20 @@ static int csi_set_rate(struct clk *clk, unsigned long rate) reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET; __raw_writel(reg, MXC_CCM_PDR0); + clk->rate = rate; return 0; } -static unsigned long ssi1_get_rate(struct clk *clk) +static void _clk_per_recalc(struct clk *clk) +{ + unsigned long per_pdf; + + per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK, + MXC_CCM_PDR0_PER_PODF_OFFSET); + clk->rate = clk->parent->rate / (per_pdf + 1); +} + +static void _clk_ssi1_recalc(struct clk *clk) { unsigned long ssi1_pdf, ssi1_prepdf; @@ -311,10 +456,10 @@ static unsigned long ssi1_get_rate(struct clk *clk) MXC_CCM_PDR1_SSI1_PODF_OFFSET); ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK, MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); + clk->rate = clk->parent->rate / (ssi1_prepdf + 1) / (ssi1_pdf + 1); } -static unsigned long ssi2_get_rate(struct clk *clk) +static void _clk_ssi2_recalc(struct clk *clk) { unsigned long ssi2_pdf, ssi2_prepdf; @@ -322,10 +467,10 @@ static unsigned long ssi2_get_rate(struct clk *clk) MXC_CCM_PDR1_SSI2_PODF_OFFSET); ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK, MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); + clk->rate = clk->parent->rate / (ssi2_prepdf + 1) / (ssi2_pdf + 1); } -static unsigned long firi_get_rate(struct clk *clk) +static void _clk_firi_recalc(struct clk *clk) { unsigned long firi_pdf, firi_prepdf; @@ -333,10 +478,10 @@ static unsigned long firi_get_rate(struct clk *clk) MXC_CCM_PDR1_FIRI_PODF_OFFSET); firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK, MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET); - return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); + clk->rate = clk->parent->rate / (firi_prepdf + 1) / (firi_pdf + 1); } -static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) +static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) { u32 pre, post; u32 parent = clk_get_rate(clk->parent); @@ -351,7 +496,7 @@ static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) } -static int firi_set_rate(struct clk *clk, unsigned long rate) +static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) { u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); @@ -369,232 +514,724 @@ static int firi_set_rate(struct clk *clk, unsigned long rate) reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET; __raw_writel(reg, MXC_CCM_PDR1); + clk->rate = rate; return 0; } -static unsigned long mbx_get_rate(struct clk *clk) +static void _clk_mbx_recalc(struct clk *clk) { - return clk_get_rate(clk->parent) / 2; + clk->rate = clk->parent->rate / 2; } -static unsigned long mstick1_get_rate(struct clk *clk) +static void _clk_mstick1_recalc(struct clk *clk) { unsigned long msti_pdf; msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK, MXC_CCM_PDR2_MST1_PDF_OFFSET); - return clk_get_rate(clk->parent) / (msti_pdf + 1); + clk->rate = clk->parent->rate / (msti_pdf + 1); } -static unsigned long mstick2_get_rate(struct clk *clk) +static void _clk_mstick2_recalc(struct clk *clk) { unsigned long msti_pdf; msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK, MXC_CCM_PDR2_MST2_PDF_OFFSET); - return clk_get_rate(clk->parent) / (msti_pdf + 1); -} - -static unsigned long ckih_rate; - -static unsigned long clk_ckih_get_rate(struct clk *clk) -{ - return ckih_rate; + clk->rate = clk->parent->rate / (msti_pdf + 1); } static struct clk ckih_clk = { - .get_rate = clk_ckih_get_rate, + .name = "ckih", + .rate = 0, /* determined later (26 or 27 MHz) */ + .flags = RATE_PROPAGATES, +}; + +static struct clk ckil_clk = { + .name = "ckil", + .rate = CKIL_CLK_FREQ, + .flags = RATE_PROPAGATES, }; static struct clk mcu_pll_clk = { + .name = "mcu_pll", .parent = &ckih_clk, - .get_rate = mcu_pll_get_rate, + .set_rate = _clk_pll_set_rate, + .recalc = _clk_pll_recalc, + .flags = RATE_PROPAGATES, }; static struct clk mcu_main_clk = { + .name = "mcu_main_clk", .parent = &mcu_pll_clk, - .get_rate = mcu_main_get_rate, + .recalc = _clk_mcu_main_recalc, }; static struct clk serial_pll_clk = { + .name = "serial_pll", .parent = &ckih_clk, - .get_rate = serial_pll_get_rate, - .enable = serial_pll_enable, - .disable = serial_pll_disable, + .set_rate = _clk_pll_set_rate, + .recalc = _clk_pll_recalc, + .enable = _clk_serial_pll_enable, + .disable = _clk_serial_pll_disable, + .flags = RATE_PROPAGATES, }; static struct clk usb_pll_clk = { + .name = "usb_pll", .parent = &ckih_clk, - .get_rate = usb_pll_get_rate, - .enable = usb_pll_enable, - .disable = usb_pll_disable, + .set_rate = _clk_pll_set_rate, + .recalc = _clk_pll_recalc, + .enable = _clk_usb_pll_enable, + .disable = _clk_usb_pll_disable, + .flags = RATE_PROPAGATES, +}; + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &mcu_main_clk, + .recalc = _clk_cpu_recalc, + .set_rate = _clk_cpu_set_rate, }; static struct clk ahb_clk = { + .name = "ahb_clk", .parent = &mcu_main_clk, - .get_rate = ahb_get_rate, -}; - -#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = gr, \ - .enable = cgr_enable, \ - .disable = cgr_disable, \ - .secondary = s, \ - .parent = p, \ - } + .recalc = _clk_hclk_recalc, + .flags = RATE_PROPAGATES, +}; -#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ - static struct clk name = { \ - .id = i, \ - .enable_reg = er, \ - .enable_shift = es, \ - .get_rate = getsetround##_get_rate, \ - .set_rate = getsetround##_set_rate, \ - .round_rate = getsetround##_round_rate, \ - .enable = cgr_enable, \ - .disable = cgr_disable, \ - .secondary = s, \ - .parent = p, \ - } +static struct clk per_clk = { + .name = "per_clk", + .parent = &usb_pll_clk, + .recalc = _clk_per_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk perclk_clk = { + .name = "perclk_clk", + .parent = &ipg_clk, + .flags = RATE_PROPAGATES, +}; + +static struct clk cspi_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET, + .disable = _clk_disable,}, + { + .name = "cspi_clk", + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .recalc = _clk_ipg_recalc, + .flags = RATE_PROPAGATES, +}; + +static struct clk emi_clk = { + .name = "emi_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_EMI_OFFSET, + .disable = _clk_emi_disable, +}; + +static struct clk gpt_clk = { + .name = "gpt_clk", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_GPT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk pwm_clk = { + .name = "pwm", + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_PWM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk epit_clk[] = { + { + .name = "epit_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET, + .disable = _clk_disable,}, + { + .name = "epit_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk nfc_clk = { + .name = "nfc_clk", + .parent = &ahb_clk, + .recalc = _clk_nfc_recalc, + .set_rate = _clk_nfc_set_rate, + .round_rate = _clk_nfc_round_rate, +}; + +static struct clk scc_clk = { + .name = "scc_clk", + .parent = &ipg_clk, +}; + +static struct clk ipu_clk = { + .name = "ipu_clk", + .parent = &mcu_main_clk, + .recalc = _clk_hsp_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_IPU_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .name = "kpp_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk wdog_clk = { + .name = "wdog_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET, + .disable = _clk_disable, +}; +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_RTC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk usb_clk[] = { + { + .name = "usb_clk", + .parent = &usb_pll_clk, + .recalc = _clk_usb_recalc,}, + { + .name = "usb_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk csi_clk = { + .name = "csi_clk", + .parent = &serial_pll_clk, + .recalc = _clk_csi_recalc, + .round_rate = _clk_csi_round_rate, + .set_rate = _clk_csi_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_CSI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk uart_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 3, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, + .disable = _clk_disable,}, + { + .name = "uart_clk", + .id = 4, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_UART5_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET, + .disable = _clk_disable,}, + { + .name = "i2c_clk", + .id = 2, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &perclk_clk, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk sdhc_clk[] = { + { + .name = "sdhc_clk", + .id = 0, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdhc_clk", + .id = 1, + .parent = &perclk_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET, + .disable = _clk_disable,}, +}; -DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); - -DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk); -DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); -DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); - -DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); -DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); -DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); -DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); - -DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); -DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); -DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); -DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); - -DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); -DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); - -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ - }, - -static struct clk_lookup lookups[] = { - _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) - _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) - _REGISTER_CLOCK(NULL, "cspi", cspi3_clk) - _REGISTER_CLOCK(NULL, "gpt", gpt_clk) - _REGISTER_CLOCK(NULL, "pwm", pwm_clk) - _REGISTER_CLOCK(NULL, "wdog", wdog_clk) - _REGISTER_CLOCK(NULL, "rtc", rtc_clk) - _REGISTER_CLOCK(NULL, "epit", epit1_clk) - _REGISTER_CLOCK(NULL, "epit", epit2_clk) - _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) - _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) - _REGISTER_CLOCK(NULL, "kpp", kpp_clk) - _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) - _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) - _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) - _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) - _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) - _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) - _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) - _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) - _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) - _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) - _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) - _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) - _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) - _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) - _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) - _REGISTER_CLOCK(NULL, "firi", firi_clk) - _REGISTER_CLOCK(NULL, "ata", ata_clk) - _REGISTER_CLOCK(NULL, "rtic", rtic_clk) - _REGISTER_CLOCK(NULL, "rng", rng_clk) - _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1) - _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) - _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) - _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) - _REGISTER_CLOCK(NULL, "scc", scc_clk) - _REGISTER_CLOCK(NULL, "iim", iim_clk) - _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) - _REGISTER_CLOCK(NULL, "mbx", mbx_clk) +static struct clk ssi_clk[] = { + { + .name = "ssi_clk", + .parent = &serial_pll_clk, + .recalc = _clk_ssi1_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET, + .disable = _clk_disable,}, + { + .name = "ssi_clk", + .id = 1, + .parent = &serial_pll_clk, + .recalc = _clk_ssi2_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET, + .disable = _clk_disable,}, }; +static struct clk firi_clk = { + .name = "firi_clk", + .parent = &usb_pll_clk, + .round_rate = _clk_firi_round_rate, + .set_rate = _clk_firi_set_rate, + .recalc = _clk_firi_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET, + .disable = _clk_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_ATA_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mbx_clk = { + .name = "mbx_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .recalc = _clk_mbx_recalc, +}; + +static struct clk vpu_clk = { + .name = "vpu_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, + .recalc = _clk_mbx_recalc, +}; + +static struct clk rtic_clk = { + .name = "rtic_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR2, + .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rng_clk = { + .name = "rng_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_RNG_OFFSET, + .disable = _clk_disable, +}; + +static struct clk sdma_clk[] = { + { + .name = "sdma_ahb_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET, + .disable = _clk_disable,}, + { + .name = "sdma_ipg_clk", + .parent = &ipg_clk,} +}; + +static struct clk mpeg4_clk = { + .name = "mpeg4_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk vl2cc_clk = { + .name = "vl2cc_clk", + .parent = &ahb_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk mstick_clk[] = { + { + .name = "mstick_clk", + .id = 0, + .parent = &usb_pll_clk, + .recalc = _clk_mstick1_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET, + .disable = _clk_disable,}, + { + .name = "mstick_clk", + .id = 1, + .parent = &usb_pll_clk, + .recalc = _clk_mstick2_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR1, + .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET, + .disable = _clk_disable,}, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CGR0, + .enable_shift = MXC_CCM_CGR0_IIM_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + if (parent % rate) + div++; + + if (div > 8) + div = 16; + else if (div > 4) + div = 8; + else if (div > 2) + div = 4; + + return parent / div; +} + +static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, parent = clk_get_rate(clk->parent); + + div = parent / rate; + + if (div == 16) + div = 4; + else if (div == 8) + div = 3; + else if (div == 4) + div = 2; + else if (div == 2) + div = 1; + else if (div == 1) + div = 0; + else + return -EINVAL; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK; + reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static void _clk_cko1_recalc(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >> + MXC_CCM_COSR_CLKOUTDIV_OFFSET; + + clk->rate = clk->parent->rate / (1 << div); +} + +static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK; + + if (parent == &mcu_main_clk) + reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipg_clk) + reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &usb_pll_clk) + reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == mcu_main_clk.parent) + reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ahb_clk) + reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &cpu_clk) + reg |= 6 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &serial_pll_clk) + reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &emi_clk) + reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &ipu_clk) + reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &nfc_clk) + reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET; + else if (parent == &uart_clk[0]) + reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET; + else + return -EINVAL; + + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static int _clk_cko1_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); + + return 0; +} + +static void _clk_cko1_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN; + __raw_writel(reg, MXC_CCM_COSR); +} + +static struct clk cko1_clk = { + .name = "cko1_clk", + .recalc = _clk_cko1_recalc, + .set_rate = _clk_cko1_set_rate, + .round_rate = _clk_cko1_round_rate, + .set_parent = _clk_cko1_set_parent, + .enable = _clk_cko1_enable, + .disable = _clk_cko1_disable, +}; + +static struct clk *mxc_clks[] = { + &ckih_clk, + &ckil_clk, + &mcu_pll_clk, + &usb_pll_clk, + &serial_pll_clk, + &mcu_main_clk, + &cpu_clk, + &ahb_clk, + &per_clk, + &perclk_clk, + &cko1_clk, + &emi_clk, + &cspi_clk[0], + &cspi_clk[1], + &cspi_clk[2], + &ipg_clk, + &gpt_clk, + &pwm_clk, + &wdog_clk, + &rtc_clk, + &epit_clk[0], + &epit_clk[1], + &nfc_clk, + &ipu_clk, + &kpp_clk, + &usb_clk[0], + &usb_clk[1], + &csi_clk, + &uart_clk[0], + &uart_clk[1], + &uart_clk[2], + &uart_clk[3], + &uart_clk[4], + &i2c_clk[0], + &i2c_clk[1], + &i2c_clk[2], + &owire_clk, + &sdhc_clk[0], + &sdhc_clk[1], + &ssi_clk[0], + &ssi_clk[1], + &firi_clk, + &ata_clk, + &rtic_clk, + &rng_clk, + &sdma_clk[0], + &sdma_clk[1], + &mstick_clk[0], + &mstick_clk[1], + &scc_clk, + &iim_clk, +}; + +static int cpu_curr_wp; +static struct cpu_wp *cpu_wp_tbl; + +static int cpu_wp_nr; + +extern void propagate_rate(struct clk *tclk); + int __init mx31_clocks_init(unsigned long fref) { u32 reg; - int i; + struct clk **clkp; - ckih_rate = fref; + ckil_clk.rate = 32768; + ckih_clk.rate = fref; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); - /* change the csi_clk parent if necessary */ - reg = __raw_readl(MXC_CCM_CCMR); - if (!(reg & MXC_CCM_CCMR_CSCS)) - if (clk_set_parent(&csi_clk, &usb_pll_clk)) - pr_err("%s: error changing csi_clk parent\n", __func__); + if (cpu_is_mx31()) { + clk_register(&mpeg4_clk); + clk_register(&mbx_clk); + } else { + clk_register(&vpu_clk); + clk_register(&vl2cc_clk); + } + /* CCMR stby control */ + reg = __raw_readl(MXC_CCM_CCMR); + reg |= MXC_CCM_CCMR_VSTBY | MXC_CCM_CCMR_WAMO; + __raw_writel(reg, MXC_CCM_CCMR); /* Turn off all possible clocks */ - __raw_writel((3 << 4), MXC_CCM_CGR0); + __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0); __raw_writel(0, MXC_CCM_CGR1); - __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| - 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for - MX32, but still required to be set */ - MXC_CCM_CGR2); - /* - * Before turning off usb_pll make sure ipg_per_clk is generated - * by ipg_clk and not usb_pll. - */ - __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR); + reg = MXC_CCM_CGR2_EMI_MASK | /*For MX32 */ + MXC_CCM_CGR2_IPMUX1_MASK | /*For MX32 */ + MXC_CCM_CGR2_IPMUX2_MASK | /*For MX32 */ + MXC_CCM_CGR2_MXCCLKENSEL_MASK | /*For MX32 */ + MXC_CCM_CGR2_CHIKCAMPEN_MASK | /*For MX32 */ + MXC_CCM_CGR2_OVRVPUBUSY_MASK | /*For MX32 */ + 0x3 << 27 | /*Bit 27 and 28 are not defined for MX32, + but still requires to be set */ + MXC_CCM_CGR2_APMSYSCLKSEL_MASK | MXC_CCM_CGR2_AOMENA_MASK; + __raw_writel(reg, MXC_CCM_CGR2); + + clk_disable(&cko1_clk); + clk_disable(&usb_pll_clk); - usb_pll_disable(&usb_pll_clk); + pr_info("Clock input source is %ld\n", ckih_clk.rate); - pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); + /* This will propagate to all children and init all the clock rates */ + propagate_rate(&ckih_clk); clk_enable(&gpt_clk); clk_enable(&emi_clk); @@ -602,15 +1239,173 @@ int __init mx31_clocks_init(unsigned long fref) clk_enable(&serial_pll_clk); - if (mx31_revision() >= CHIP_REV_2_0) { - reg = __raw_readl(MXC_CCM_PMCR1); - /* No PLL restart on DVFS switch; enable auto EMI handshake */ - reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN; - __raw_writel(reg, MXC_CCM_PMCR1); + cpu_curr_wp = cpu_clk.rate / ahb_clk.rate - 1; + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + + /* Init serial PLL according */ + clk_set_rate(&serial_pll_clk, (cpu_wp_tbl[2].pll_rate)); + + if (cpu_is_mx31_rev(CHIP_REV_2_0) < 0) { + /* replace 399MHz wp with 266MHz one */ + memcpy(&cpu_wp_tbl[2], &cpu_wp_tbl[1], sizeof(cpu_wp_tbl[0])); } - mxc_timer_init(&ipg_clk); + mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT); return 0; } +#define MXC_PMCR0_DVFS_MASK (MXC_CCM_PMCR0_DVSUP_MASK | \ + MXC_CCM_PMCR0_UDSC_MASK | \ + MXC_CCM_PMCR0_VSCNT_MASK | \ + MXC_CCM_PMCR0_DPVCR) + +#define MXC_PDR0_MAX_MCU_MASK (MXC_CCM_PDR0_MAX_PODF_MASK | \ + MXC_CCM_PDR0_MCU_PODF_MASK | \ + MXC_CCM_PDR0_HSP_PODF_MASK | \ + MXC_CCM_PDR0_IPG_PODF_MASK | \ + MXC_CCM_PDR0_NFC_PODF_MASK) + +static DEFINE_SPINLOCK(mxc_dfs_lock); + +static void dptcen_after_timeout(unsigned long ptr) +{ + unsigned long flags = 0; + + spin_lock_irqsave(&mxc_dfs_lock, flags); + + /* + * If DPTC is still active and core is running in Turbo mode + */ + if (dptcen_timer.data == cpu_wp_nr - 1) { + dptc_resume(DPTC_GP_ID); + } + spin_unlock_irqrestore(&mxc_dfs_lock, flags); +} + +/*! + * Setup cpu clock based on working point. + * @param wp cpu freq working point (0 is the slowest) + * @return 0 on success or error code on failure. + */ +static int cpu_clk_set_wp(int wp) +{ + struct cpu_wp *p; + u32 dvsup; + u32 pmcr0, pmcr1; + u32 pdr0; + u32 cgr2 = 0x80000000; + u32 vscnt = MXC_CCM_PMCR0_VSCNT_2; + u32 udsc = MXC_CCM_PMCR0_UDSC_DOWN; + void __iomem *ipu_base = IO_ADDRESS(IPU_CTRL_BASE_ADDR); + u32 ipu_conf; + + if (wp >= cpu_wp_nr || wp < 0) { + printk(KERN_ERR "Wrong wp: %d for cpu_clk_set_wp\n", wp); + return -EINVAL; + } + if (wp == cpu_curr_wp) { + return 0; + } + + pmcr0 = __raw_readl(MXC_CCM_PMCR0); + pmcr1 = __raw_readl(MXC_CCM_PMCR1); + pdr0 = __raw_readl(MXC_CCM_PDR0); + + if (!(pmcr0 & MXC_CCM_PMCR0_UPDTEN)) { + return -EBUSY; + } + + if (wp > cpu_curr_wp) { + /* going faster */ + if (wp == (cpu_wp_nr - 1)) { + /* Only update vscnt going into Turbo */ + vscnt = MXC_CCM_PMCR0_VSCNT_8; + } + udsc = MXC_CCM_PMCR0_UDSC_UP; + } + + p = &cpu_wp_tbl[wp]; + + dvsup = (cpu_wp_nr - 1 - wp) << MXC_CCM_PMCR0_DVSUP_OFFSET; + + if ((mcu_main_clk.rate == 399000000) && (p->cpu_rate == 532000000)) { + cgr2 = __raw_readl(MXC_CCM_CGR2); + cgr2 &= 0x7fffffff; + vscnt = 0; + pmcr0 = (pmcr0 & ~MXC_PMCR0_DVFS_MASK) | dvsup | vscnt; + pr_debug("manul dvfs, dvsup = %x\n", dvsup); + __raw_writel(cgr2, MXC_CCM_CGR2); + __raw_writel(pmcr0, MXC_CCM_PMCR0); + udelay(100); + } + + if (mcu_main_clk.rate == p->pll_rate) { + /* No pll switching and relocking needed */ + pmcr0 |= MXC_CCM_PMCR0_DFSUP0_PDR; + } else { + /* pll switching and relocking needed */ + pmcr0 ^= MXC_CCM_PMCR0_DFSUP1; /* flip MSB bit */ + pmcr0 &= ~(MXC_CCM_PMCR0_DFSUP0); + } + + pmcr0 = (pmcr0 & ~MXC_PMCR0_DVFS_MASK) | dvsup | vscnt | udsc; + /* also enable DVFS hardware */ + pmcr0 |= MXC_CCM_PMCR0_DVFEN; + + __raw_writel(pmcr0, MXC_CCM_PMCR0); + + /* IPU and DI submodule must be on for PDR0 update to take effect */ + if (!clk_get_usecount(&ipu_clk)) + ipu_clk.enable(&ipu_clk); + ipu_conf = __raw_readl(ipu_base); + if (!(ipu_conf & 0x40)) + __raw_writel(ipu_conf | 0x40, ipu_base); + + __raw_writel((pdr0 & ~MXC_PDR0_MAX_MCU_MASK) | p->pdr0_reg, + MXC_CCM_PDR0); + + if ((pmcr0 & MXC_CCM_PMCR0_DFSUP0) == MXC_CCM_PMCR0_DFSUP0_PLL) { + /* prevent pll restart */ + pmcr1 |= 0x80; + __raw_writel(pmcr1, MXC_CCM_PMCR1); + /* PLL and post divider update */ + if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) { + __raw_writel(p->pll_reg, MXC_CCM_SRPCTL); + serial_pll_clk.rate = p->pll_rate; + mcu_main_clk.parent = &serial_pll_clk; + } else { + __raw_writel(p->pll_reg, MXC_CCM_MPCTL); + mcu_pll_clk.rate = p->pll_rate; + mcu_main_clk.parent = &mcu_pll_clk; + } + } + + if ((cgr2 & 0x80000000) == 0x0) { + pr_debug("start auto dvfs\n"); + cgr2 |= 0x80000000; + __raw_writel(cgr2, MXC_CCM_CGR2); + } + + mcu_main_clk.rate = p->pll_rate; + cpu_clk.rate = p->cpu_rate; + + cpu_curr_wp = wp; + + /* Restore IPU_CONF setting */ + __raw_writel(ipu_conf, ipu_base); + if (!clk_get_usecount(&ipu_clk)) + ipu_clk.disable(&ipu_clk); + + if (wp == cpu_wp_nr - 1) { + init_timer(&dptcen_timer); + dptcen_timer.expires = jiffies + 2; + dptcen_timer.function = dptcen_after_timeout; + dptcen_timer.data = wp; + add_timer(&dptcen_timer); + } else { + dptc_suspend(DPTC_GP_ID); + } + + return 0; +} diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c new file mode 100644 index 000000000000..c89dfab910c2 --- /dev/null +++ b/arch/arm/mach-mx3/cpu.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2001 Deep Blue Solutions Ltd. + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +/*! + * @file mach-mx3/cpu.c + * + * @brief This file contains the CPU initialization code. + * + * @ingroup MSL_MX31 + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <mach/hardware.h> +#include <linux/io.h> +#include <asm/hardware/cache-l2x0.h> + +/*! + * CPU initialization. It is called by fixup_mxc_board() + */ +void __init mxc_cpu_init(void) +{ + /* Setup Peripheral Port Remap register for AVIC */ + asm("ldr r0, =0xC0000015 \n\ + mcr p15, 0, r0, c15, c2, 4"); + if (!system_rev) { + mxc_set_system_rev(0x31, CHIP_REV_2_0); + } +} + +/*! + * Post CPU init code + * + * @return 0 always + */ +static int __init post_cpu_init(void) +{ + volatile unsigned long aips_reg; + + /* + * S/W workaround: Clear the off platform peripheral modules + * Supervisor Protect bit for SDMA to access them. + */ + __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x40)); + __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x44)); + __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x48)); + __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x4C)); + aips_reg = __raw_readl(IO_ADDRESS(AIPS1_BASE_ADDR + 0x50)); + aips_reg &= 0x00FFFFFF; + __raw_writel(aips_reg, IO_ADDRESS(AIPS1_BASE_ADDR + 0x50)); + + __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x40)); + __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x44)); + __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x48)); + __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x4C)); + aips_reg = __raw_readl(IO_ADDRESS(AIPS2_BASE_ADDR + 0x50)); + aips_reg &= 0x00FFFFFF; + __raw_writel(aips_reg, IO_ADDRESS(AIPS2_BASE_ADDR + 0x50)); + + return 0; +} + +postcore_initcall(post_cpu_init); diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h index adfa3627ad84..04d4d7c12086 100644 --- a/arch/arm/mach-mx3/crm_regs.h +++ b/arch/arm/mach-mx3/crm_regs.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> * * This program is free software; you can redistribute it and/or @@ -24,7 +24,7 @@ #define CKIH_CLK_FREQ_27MHZ 27000000 #define CKIL_CLK_FREQ 32768 -#define MXC_CCM_BASE IO_ADDRESS(CCM_BASE_ADDR) +#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR)) /* Register addresses */ #define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) @@ -55,6 +55,7 @@ #define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) /* Register bit definitions */ +#define MXC_CCM_CCMR_VSTBY (1 << 28) #define MXC_CCM_CCMR_WBEN (1 << 27) #define MXC_CCM_CCMR_CSCS (1 << 25) #define MXC_CCM_CCMR_PERCS (1 << 24) @@ -66,6 +67,7 @@ #define MXC_CCM_CCMR_LPM_MASK (0x3 << 14) #define MXC_CCM_CCMR_FIRS_OFFSET 11 #define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11) +#define MXC_CCM_CCMR_WAMO (1 << 10) #define MXC_CCM_CCMR_UPE (1 << 9) #define MXC_CCM_CCMR_SPE (1 << 8) #define MXC_CCM_CCMR_MDS (1 << 7) @@ -91,6 +93,47 @@ #define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 #define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 +#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11) +#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11) +#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11) +#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11) +#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11) +#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11) +#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11) +#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11) + +#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6) +#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6) +#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6) +#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6) + +#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3) +#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3) +#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3) +#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3) +#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3) +#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3) +#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3) +#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3) + +#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8) +#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8) +#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8) +#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8) +#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8) +#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8) +#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8) +#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8) + +#define MXC_CCM_PDR0_MCU_DIV_1 0x0 +#define MXC_CCM_PDR0_MCU_DIV_2 0x1 +#define MXC_CCM_PDR0_MCU_DIV_3 0x2 +#define MXC_CCM_PDR0_MCU_DIV_4 0x3 +#define MXC_CCM_PDR0_MCU_DIV_5 0x4 +#define MXC_CCM_PDR0_MCU_DIV_6 0x5 +#define MXC_CCM_PDR0_MCU_DIV_7 0x6 +#define MXC_CCM_PDR0_MCU_DIV_8 0x7 + #define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 #define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) #define MXC_CCM_PDR1_USB_PODF_OFFSET 27 @@ -109,7 +152,120 @@ #define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F /* Bit definitions for RCSR */ -#define MXC_CCM_RCSR_NF16B 0x80000000 +#define MXC_CCM_RCSR_NF16B (0x1 << 31) +#define MXC_CCM_RCSR_NFMS (0x1 << 30) + +/* Bit definitions for both MCU, USB and SR PLL control registers */ +#define MXC_CCM_PCTL_BRM 0x80000000 +#define MXC_CCM_PCTL_PD_OFFSET 26 +#define MXC_CCM_PCTL_PD_MASK (0xF << 26) +#define MXC_CCM_PCTL_MFD_OFFSET 16 +#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16) +#define MXC_CCM_PCTL_MFI_OFFSET 10 +#define MXC_CCM_PCTL_MFI_MASK (0xF << 10) +#define MXC_CCM_PCTL_MFN_OFFSET 0 +#define MXC_CCM_PCTL_MFN_MASK 0x3FF + +#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0 +#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0) +#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2 +#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2) +#define MXC_CCM_CGR0_GPT_OFFSET 4 +#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4) +#define MXC_CCM_CGR0_EPIT1_OFFSET 6 +#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6) +#define MXC_CCM_CGR0_EPIT2_OFFSET 8 +#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8) +#define MXC_CCM_CGR0_IIM_OFFSET 10 +#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10) +#define MXC_CCM_CGR0_ATA_OFFSET 12 +#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12) +#define MXC_CCM_CGR0_SDMA_OFFSET 14 +#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14) +#define MXC_CCM_CGR0_CSPI3_OFFSET 16 +#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16) +#define MXC_CCM_CGR0_RNG_OFFSET 18 +#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18) +#define MXC_CCM_CGR0_UART1_OFFSET 20 +#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20) +#define MXC_CCM_CGR0_UART2_OFFSET 22 +#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22) +#define MXC_CCM_CGR0_SSI1_OFFSET 24 +#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24) +#define MXC_CCM_CGR0_I2C1_OFFSET 26 +#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26) +#define MXC_CCM_CGR0_I2C2_OFFSET 28 +#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28) +#define MXC_CCM_CGR0_I2C3_OFFSET 30 +#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30) + +#define MXC_CCM_CGR1_HANTRO_OFFSET 0 +#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0) +#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2 +#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2) +#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4 +#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4) +#define MXC_CCM_CGR1_CSI_OFFSET 6 +#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6) +#define MXC_CCM_CGR1_RTC_OFFSET 8 +#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8) +#define MXC_CCM_CGR1_WDOG_OFFSET 10 +#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10) +#define MXC_CCM_CGR1_PWM_OFFSET 12 +#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12) +#define MXC_CCM_CGR1_SIM_OFFSET 14 +#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14) +#define MXC_CCM_CGR1_ECT_OFFSET 16 +#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16) +#define MXC_CCM_CGR1_USBOTG_OFFSET 18 +#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18) +#define MXC_CCM_CGR1_KPP_OFFSET 20 +#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20) +#define MXC_CCM_CGR1_IPU_OFFSET 22 +#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22) +#define MXC_CCM_CGR1_UART3_OFFSET 24 +#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24) +#define MXC_CCM_CGR1_UART4_OFFSET 26 +#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26) +#define MXC_CCM_CGR1_UART5_OFFSET 28 +#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28) +#define MXC_CCM_CGR1_OWIRE_OFFSET 30 +#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30) + +#define MXC_CCM_CGR2_SSI2_OFFSET 0 +#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0) +#define MXC_CCM_CGR2_CSPI1_OFFSET 2 +#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2) +#define MXC_CCM_CGR2_CSPI2_OFFSET 4 +#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4) +#define MXC_CCM_CGR2_GACC_OFFSET 6 +#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6) +#define MXC_CCM_CGR2_EMI_OFFSET 8 +#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8) +#define MXC_CCM_CGR2_RTIC_OFFSET 10 +#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10) +#define MXC_CCM_CGR2_FIRI_OFFSET 12 +#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12) +#define MXC_CCM_CGR2_IPMUX1_OFFSET 14 +#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14) +#define MXC_CCM_CGR2_IPMUX2_OFFSET 16 +#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16) + +/* These new CGR2 bits are added in MX32 */ +#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18 +#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18) +#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20 +#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20) +#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22 +#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22) +#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24 +#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24) +#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25 +#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25) +#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26 +#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26) +#define MXC_CCM_CGR2_APMENA_OFFSET 30 +#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30) /* * LTR0 register offsets diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 9e87e08fb121..f4a3cdd502bd 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -1,434 +1,901 @@ /* - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Sascha Hauer, kernel@pengutronix.de + * Author: MontaVista Software, Inc. + * <source@mvista.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Based on the OMAP devices.c * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is + * licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. */ - -#include <linux/dma-mapping.h> #include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> #include <linux/platform_device.h> -#include <linux/serial.h> -#include <linux/gpio.h> +#include <linux/clk.h> +#include <linux/pmic_external.h> + +#include <linux/spi/spi.h> + +#include <asm/mach-types.h> #include <mach/hardware.h> -#include <mach/irqs.h> -#include <mach/common.h> -#include <mach/imx-uart.h> -#include <mach/mx3_camera.h> +#include <mach/pmic_power.h> +#include <mach/spba.h> +#include <mach/sdma.h> +#include <mach/mxc_dptc.h> +#include <mach/gpio.h> + +#include "iomux.h" +#include "crm_regs.h" +#include "sdma_script_code.h" +#include "sdma_script_code_pass2.h" + +extern struct dptc_wp dptc_wp_allfreq_26ckih[DPTC_WP_SUPPORTED]; +extern struct dptc_wp dptc_wp_allfreq_26ckih_TO_2_0[DPTC_WP_SUPPORTED]; +extern struct dptc_wp dptc_wp_allfreq_27ckih_TO_2_0[DPTC_WP_SUPPORTED]; +/* + * Clock structures + */ +static struct clk *ckih_clk; + +void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr) +{ + if (cpu_is_mx31_rev(CHIP_REV_1_0) == 1) { + sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR; + sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1; + sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1; + sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR; + sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; + sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_start_addr = + (unsigned short *)sdma_code; + sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = + uartsh_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE; + sdma_script_addr->mxc_sdma_ram_code_start_addr = + RAM_CODE_START_ADDR; + sdma_script_addr->mxc_sdma_dptc_dvfs_addr = dptc_dvfs_ADDR; + sdma_script_addr->mxc_sdma_firi_2_mcu_addr = firi_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; + sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = mshc_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_per_2_app_addr = -1; + sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; + sdma_script_addr->mxc_sdma_per_2_shp_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_firi_addr = mcu_2_firi_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = mcu_2_mshc_ADDR; + sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_uartsh_2_per_addr = -1; + sdma_script_addr->mxc_sdma_shp_2_per_addr = -1; + sdma_script_addr->mxc_sdma_uart_2_per_addr = -1; + sdma_script_addr->mxc_sdma_app_2_per_addr = -1; + } else { + sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR_2; + sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr = + ap_2_ap_fixed_addr_ADDR_2; + sdma_script_addr->mxc_sdma_ap_2_bp_addr = ap_2_bp_ADDR_2; + sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr = + ap_2_ap_fixed_addr_ADDR_2; + sdma_script_addr->mxc_sdma_bp_2_ap_addr = bp_2_ap_ADDR_2; + sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR_2; + sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR_2; + sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; + sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_start_addr = + (unsigned short *)sdma_code_2; + sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = + uartsh_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE_2; + sdma_script_addr->mxc_sdma_ram_code_start_addr = + RAM_CODE_START_ADDR_2; + sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; + sdma_script_addr->mxc_sdma_firi_2_mcu_addr = firi_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; + sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = mshc_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR_2; + sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; + sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR_2; + sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR_2; + sdma_script_addr->mxc_sdma_mcu_2_firi_addr = mcu_2_firi_ADDR_2; + sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = mcu_2_mshc_ADDR_2; + sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR_2; + sdma_script_addr->mxc_sdma_uartsh_2_per_addr = -1; + sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR_2; + sdma_script_addr->mxc_sdma_uart_2_per_addr = -1; + sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR_2; + } +} + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE) +static struct mxc_w1_config mxc_w1_data = { + .search_rom_accelerator = 0, +}; -#include "devices.h" +static struct platform_device mxc_w1_devices = { + .name = "mxc_w1", + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_w1_data, + }, + .id = 0 +}; + +static void mxc_init_owire(void) +{ + (void)platform_device_register(&mxc_w1_devices); +} +#else +static inline void mxc_init_owire(void) +{ +} +#endif -static struct resource uart0[] = { +#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE) +static struct resource rtc_resources[] = { { - .start = UART1_BASE_ADDR, - .end = UART1_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_UART1, - .end = MXC_INT_UART1, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device0 = { - .name = "imx-uart", + .start = RTC_BASE_ADDR, + .end = RTC_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_RTC, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device mxc_rtc_device = { + .name = "mxc_rtc", .id = 0, - .resource = uart0, - .num_resources = ARRAY_SIZE(uart0), + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, }; +static void mxc_init_rtc(void) +{ + (void)platform_device_register(&mxc_rtc_device); +} +#else +static inline void mxc_init_rtc(void) +{ +} +#endif -static struct resource uart1[] = { +#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE) + +static struct resource wdt_resources[] = { { - .start = UART2_BASE_ADDR, - .end = UART2_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_UART2, - .end = MXC_INT_UART2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device1 = { - .name = "imx-uart", - .id = 1, - .resource = uart1, - .num_resources = ARRAY_SIZE(uart1), + .start = WDOG1_BASE_ADDR, + .end = WDOG1_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, }; -static struct resource uart2[] = { - { - .start = UART3_BASE_ADDR, - .end = UART3_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_UART3, - .end = MXC_INT_UART3, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device2 = { - .name = "imx-uart", - .id = 2, - .resource = uart2, - .num_resources = ARRAY_SIZE(uart2), +static struct platform_device mxc_wdt_device = { + .name = "mxc_wdt", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, }; -#ifdef CONFIG_ARCH_MX31 -static struct resource uart3[] = { +static void mxc_init_wdt(void) +{ + (void)platform_device_register(&mxc_wdt_device); +} +#else +static inline void mxc_init_wdt(void) +{ +} +#endif + +#if defined(CONFIG_MXC_IPU) || defined(CONFIG_MXC_IPU_MODULE) +static struct mxc_ipu_config mxc_ipu_data = { + .rev = 1, +}; + +static struct resource ipu_resources[] = { + { + .start = IPU_CTRL_BASE_ADDR, + .end = IPU_CTRL_BASE_ADDR + SZ_4K, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_IPU_SYN, + .flags = IORESOURCE_IRQ, + }, { - .start = UART4_BASE_ADDR, - .end = UART4_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_UART4, - .end = MXC_INT_UART4, - .flags = IORESOURCE_IRQ, - }, + .start = MXC_INT_IPU_ERR, + .flags = IORESOURCE_IRQ, + }, }; -struct platform_device mxc_uart_device3 = { - .name = "imx-uart", - .id = 3, - .resource = uart3, - .num_resources = ARRAY_SIZE(uart3), +static struct platform_device mxc_ipu_device = { + .name = "mxc_ipu", + .id = -1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_ipu_data, + }, + .num_resources = ARRAY_SIZE(ipu_resources), + .resource = ipu_resources, }; -static struct resource uart4[] = { - { - .start = UART5_BASE_ADDR, - .end = UART5_BASE_ADDR + 0x0B5, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_UART5, - .end = MXC_INT_UART5, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device4 = { - .name = "imx-uart", - .id = 4, - .resource = uart4, - .num_resources = ARRAY_SIZE(uart4), -}; -#endif /* CONFIG_ARCH_MX31 */ - -/* GPIO port description */ -static struct mxc_gpio_port imx_gpio_ports[] = { - [0] = { - .chip.label = "gpio-0", - .base = IO_ADDRESS(GPIO1_BASE_ADDR), - .irq = MXC_INT_GPIO1, - .virtual_irq_start = MXC_GPIO_IRQ_START, - }, - [1] = { - .chip.label = "gpio-1", - .base = IO_ADDRESS(GPIO2_BASE_ADDR), - .irq = MXC_INT_GPIO2, - .virtual_irq_start = MXC_GPIO_IRQ_START + 32, - }, - [2] = { - .chip.label = "gpio-2", - .base = IO_ADDRESS(GPIO3_BASE_ADDR), - .irq = MXC_INT_GPIO3, - .virtual_irq_start = MXC_GPIO_IRQ_START + 64, - } +static void mxc_init_ipu(void) +{ + platform_device_register(&mxc_ipu_device); +} +#else +static inline void mxc_init_ipu(void) +{ +} +#endif + +#if defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE) +static struct mxc_audio_platform_data mxc_audio_data; + +static struct platform_device mxc_alsa_device = { + .name = "mxc_alsa", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_audio_data, + }, + }; -int __init mxc_register_gpios(void) +static void mxc_init_audio(void) { - return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); + struct clk *pll_clk; + pll_clk = clk_get(NULL, "usb_pll"); + mxc_audio_data.ssi_clk[0] = clk_get(NULL, "ssi_clk.0"); + clk_set_parent(mxc_audio_data.ssi_clk[0], pll_clk); + clk_put(mxc_audio_data.ssi_clk[0]); + if (machine_is_mx31_3ds()) { + mxc_audio_data.ssi_num = 1; + } else { + mxc_audio_data.ssi_num = 2; + mxc_audio_data.ssi_clk[1] = clk_get(NULL, "ssi_clk.1"); + clk_set_parent(mxc_audio_data.ssi_clk[1], pll_clk); + clk_put(mxc_audio_data.ssi_clk[1]); + } + clk_put(pll_clk); + mxc_audio_data.src_port = 0; + platform_device_register(&mxc_alsa_device); } +#else -static struct resource mxc_w1_master_resources[] = { - { - .start = OWIRE_BASE_ADDR, - .end = OWIRE_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, +static void mxc_init_audio(void) +{ +} + +#endif + +#if defined(CONFIG_MXC_SSI) || defined(CONFIG_MXC_SSI_MODULE) +/*! + * Resource definition for the SSI + */ +static struct resource mxcssi2_resources[] = { + [0] = { + .start = SSI2_BASE_ADDR, + .end = SSI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, }; -struct platform_device mxc_w1_master_device = { - .name = "mxc_w1", +static struct resource mxcssi1_resources[] = { + [0] = { + .start = SSI1_BASE_ADDR, + .end = SSI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +/*! Device Definition for MXC SSI */ +static struct platform_device mxc_ssi1_device = { + .name = "mxc_ssi", .id = 0, - .num_resources = ARRAY_SIZE(mxc_w1_master_resources), - .resource = mxc_w1_master_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_audio_data, + }, + .num_resources = ARRAY_SIZE(mxcssi1_resources), + .resource = mxcssi1_resources, }; -static struct resource mxc_nand_resources[] = { - { - .start = 0, /* runtime dependent */ - .end = 0, - .flags = IORESOURCE_MEM - }, { - .start = MXC_INT_NANDFC, - .end = MXC_INT_NANDFC, - .flags = IORESOURCE_IRQ - }, -}; - -struct platform_device mxc_nand_device = { - .name = "mxc_nand", +static struct platform_device mxc_ssi2_device = { + .name = "mxc_ssi", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_audio_data, + }, + .num_resources = ARRAY_SIZE(mxcssi2_resources), + .resource = mxcssi2_resources, +}; + +static void mxc_init_ssi(void) +{ + platform_device_register(&mxc_ssi1_device); + platform_device_register(&mxc_ssi2_device); +} +#else + +static void mxc_init_ssi(void) +{ +} +#endif + +/*! + * This is platform device structure for adding SCC + */ +#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE) +static struct platform_device mxc_scc_device = { + .name = "mxc_scc", .id = 0, - .num_resources = ARRAY_SIZE(mxc_nand_resources), - .resource = mxc_nand_resources, }; -static struct resource mxc_i2c0_resources[] = { - { - .start = I2C_BASE_ADDR, - .end = I2C_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_I2C, - .end = MXC_INT_I2C, - .flags = IORESOURCE_IRQ, - }, +static void mxc_init_scc(void) +{ + platform_device_register(&mxc_scc_device); +} +#else +static inline void mxc_init_scc(void) +{ +} +#endif + +/* SPI controller and device data */ +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + +#ifdef CONFIG_SPI_MXC_SELECT1 +/*! + * Resource definition for the CSPI1 + */ +static struct resource mxcspi1_resources[] = { + [0] = { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI1, + .end = MXC_INT_CSPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI1 */ +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 4, + .spi_version = 4, }; -struct platform_device mxc_i2c_device0 = { - .name = "imx-i2c", +/*! Device Definition for MXC CSPI1 */ +static struct platform_device mxcspi1_device = { + .name = "mxc_spi", .id = 0, - .num_resources = ARRAY_SIZE(mxc_i2c0_resources), - .resource = mxc_i2c0_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi1_data, + }, + .num_resources = ARRAY_SIZE(mxcspi1_resources), + .resource = mxcspi1_resources, }; -static struct resource mxc_i2c1_resources[] = { - { - .start = I2C2_BASE_ADDR, - .end = I2C2_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_I2C2, - .end = MXC_INT_I2C2, - .flags = IORESOURCE_IRQ, - }, +#endif /* CONFIG_SPI_MXC_SELECT1 */ + +#ifdef CONFIG_SPI_MXC_SELECT2 +/*! + * Resource definition for the CSPI2 + */ +static struct resource mxcspi2_resources[] = { + [0] = { + .start = CSPI2_BASE_ADDR, + .end = CSPI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI2, + .end = MXC_INT_CSPI2, + .flags = IORESOURCE_IRQ, + }, }; -struct platform_device mxc_i2c_device1 = { - .name = "imx-i2c", +/*! Platform Data for MXC CSPI2 */ +static struct mxc_spi_master mxcspi2_data = { + .maxchipselect = 4, + .spi_version = 4, +}; + +/*! Device Definition for MXC CSPI2 */ +static struct platform_device mxcspi2_device = { + .name = "mxc_spi", .id = 1, - .num_resources = ARRAY_SIZE(mxc_i2c1_resources), - .resource = mxc_i2c1_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi2_data, + }, + .num_resources = ARRAY_SIZE(mxcspi2_resources), + .resource = mxcspi2_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT2 */ + +#ifdef CONFIG_SPI_MXC_SELECT3 +/*! + * Resource definition for the CSPI3 + */ +static struct resource mxcspi3_resources[] = { + [0] = { + .start = CSPI3_BASE_ADDR, + .end = CSPI3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI3, + .end = MXC_INT_CSPI3, + .flags = IORESOURCE_IRQ, + }, }; -static struct resource mxc_i2c2_resources[] = { - { - .start = I2C3_BASE_ADDR, - .end = I2C3_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = MXC_INT_I2C3, - .end = MXC_INT_I2C3, - .flags = IORESOURCE_IRQ, - }, +/*! Platform Data for MXC CSPI3 */ +static struct mxc_spi_master mxcspi3_data = { + .maxchipselect = 4, + .spi_version = 4, }; -struct platform_device mxc_i2c_device2 = { - .name = "imx-i2c", +/*! Device Definition for MXC CSPI3 */ +static struct platform_device mxcspi3_device = { + .name = "mxc_spi", .id = 2, - .num_resources = ARRAY_SIZE(mxc_i2c2_resources), - .resource = mxc_i2c2_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi3_data, + }, + .num_resources = ARRAY_SIZE(mxcspi3_resources), + .resource = mxcspi3_resources, }; +#endif /* CONFIG_SPI_MXC_SELECT3 */ -#ifdef CONFIG_ARCH_MX31 -static struct resource mxcsdhc0_resources[] = { - { - .start = MMC_SDHC1_BASE_ADDR, - .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_MMC_SDHC1, - .end = MXC_INT_MMC_SDHC1, - .flags = IORESOURCE_IRQ, - }, +static inline void mxc_init_spi(void) +{ + /* SPBA configuration for CSPI2 - MCU is set */ + spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A); +#ifdef CONFIG_SPI_MXC_SELECT1 + if (platform_device_register(&mxcspi1_device) < 0) + printk("Error: Registering the SPI Controller_1\n"); +#endif /* CONFIG_SPI_MXC_SELECT1 */ +#ifdef CONFIG_SPI_MXC_SELECT2 + if (platform_device_register(&mxcspi2_device) < 0) + printk("Error: Registering the SPI Controller_2\n"); +#endif /* CONFIG_SPI_MXC_SELECT2 */ +#ifdef CONFIG_SPI_MXC_SELECT3 + if (platform_device_register(&mxcspi3_device) < 0) + printk("Error: Registering the SPI Controller_3\n"); +#endif /* CONFIG_SPI_MXC_SELECT3 */ +} +#else +static inline void mxc_init_spi(void) +{ +} +#endif + +/* I2C controller and device data */ +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 +/*! + * Resource definition for the I2C1 + */ +static struct resource mxci2c1_resources[] = { + [0] = { + .start = I2C_BASE_ADDR, + .end = I2C_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C, + .end = MXC_INT_I2C, + .flags = IORESOURCE_IRQ, + }, }; -static struct resource mxcsdhc1_resources[] = { - { - .start = MMC_SDHC2_BASE_ADDR, - .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_MMC_SDHC2, - .end = MXC_INT_MMC_SDHC2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxcsdhc_device0 = { - .name = "mxc-mmc", - .id = 0, - .num_resources = ARRAY_SIZE(mxcsdhc0_resources), - .resource = mxcsdhc0_resources, +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c1_data = { + .i2c_clk = 100000, }; +#endif -struct platform_device mxcsdhc_device1 = { - .name = "mxc-mmc", - .id = 1, - .num_resources = ARRAY_SIZE(mxcsdhc1_resources), - .resource = mxcsdhc1_resources, +#ifdef CONFIG_I2C_MXC_SELECT2 +/*! + * Resource definition for the I2C2 + */ +static struct resource mxci2c2_resources[] = { + [0] = { + .start = I2C2_BASE_ADDR, + .end = I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C2, + .end = MXC_INT_I2C2, + .flags = IORESOURCE_IRQ, + }, }; -static struct resource rnga_resources[] = { - { - .start = RNGA_BASE_ADDR, - .end = RNGA_BASE_ADDR + 0x28, - .flags = IORESOURCE_MEM, - }, +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c2_data = { + .i2c_clk = 100000, }; +#endif -struct platform_device mxc_rnga_device = { - .name = "mxc_rnga", - .id = -1, - .num_resources = 1, - .resource = rnga_resources, +#ifdef CONFIG_I2C_MXC_SELECT3 +/*! + * Resource definition for the I2C3 + */ +static struct resource mxci2c3_resources[] = { + [0] = { + .start = I2C3_BASE_ADDR, + .end = I2C3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C3, + .end = MXC_INT_I2C3, + .flags = IORESOURCE_IRQ, + }, }; -#endif /* CONFIG_ARCH_MX31 */ -/* i.MX31 Image Processing Unit */ +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c3_data = { + .i2c_clk = 100000, +}; +#endif -/* The resource order is important! */ -static struct resource mx3_ipu_rsrc[] = { +/*! Device Definition for MXC I2C1 */ +static struct platform_device mxci2c_devices[] = { +#ifdef CONFIG_I2C_MXC_SELECT1 { - .start = IPU_CTRL_BASE_ADDR, - .end = IPU_CTRL_BASE_ADDR + 0x5F, - .flags = IORESOURCE_MEM, - }, { - .start = IPU_CTRL_BASE_ADDR + 0x88, - .end = IPU_CTRL_BASE_ADDR + 0xB3, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_IPU_SYN, - .end = MXC_INT_IPU_SYN, - .flags = IORESOURCE_IRQ, - }, { - .start = MXC_INT_IPU_ERR, - .end = MXC_INT_IPU_ERR, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mx3_ipu = { - .name = "ipu-core", - .id = -1, - .num_resources = ARRAY_SIZE(mx3_ipu_rsrc), - .resource = mx3_ipu_rsrc, + .name = "mxc_i2c", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c1_data, + }, + .num_resources = ARRAY_SIZE(mxci2c1_resources), + .resource = mxci2c1_resources,}, +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 + { + .name = "mxc_i2c", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c2_data, + }, + .num_resources = ARRAY_SIZE(mxci2c2_resources), + .resource = mxci2c2_resources,}, +#endif +#ifdef CONFIG_I2C_MXC_SELECT3 + { + .name = "mxc_i2c", + .id = 2, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c3_data, + }, + .num_resources = ARRAY_SIZE(mxci2c3_resources), + .resource = mxci2c3_resources,}, +#endif }; -static struct resource fb_resources[] = { - { - .start = IPU_CTRL_BASE_ADDR + 0xB4, - .end = IPU_CTRL_BASE_ADDR + 0x1BF, - .flags = IORESOURCE_MEM, - }, +static inline void mxc_init_i2c(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) { + if (platform_device_register(&mxci2c_devices[i]) < 0) + dev_err(&mxci2c_devices[i].dev, + "Unable to register I2C device\n"); + } +} +#else +static inline void mxc_init_i2c(void) +{ +} +#endif + +struct mxc_gpio_port mxc_gpio_ports[] = { + [0] = { + .chip.label = "gpio-0", + .base = IO_ADDRESS(GPIO1_BASE_ADDR), + .irq = MXC_INT_GPIO1, + .irq_high = 0, + .virtual_irq_start = MXC_GPIO_IRQ_START, + }, + [1] = { + .chip.label = "gpio-1", + .base = IO_ADDRESS(GPIO2_BASE_ADDR), + .irq = MXC_INT_GPIO2, + .irq_high = 0, + .virtual_irq_start = MXC_GPIO_IRQ_START + 32, + }, + [2] = { + .chip.label = "gpio-2", + .base = IO_ADDRESS(GPIO3_BASE_ADDR), + .irq = MXC_INT_GPIO3, + .irq_high = 0, + .virtual_irq_start = MXC_GPIO_IRQ_START + 64, + } }; -struct platform_device mx3_fb = { - .name = "mx3_sdc_fb", - .id = -1, - .num_resources = ARRAY_SIZE(fb_resources), - .resource = fb_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, +int __init mxc_register_gpios(void) +{ + return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); +} + +#if defined(CONFIG_PCMCIA_MX31ADS) || defined(CONFIG_PCMCIA_MX31ADS_MODULE) + +static struct platform_device mx31ads_device = { + .name = "Mx31ads_pcmcia_socket", + .id = 0, + .dev.release = mxc_nop_release, +}; +static inline void mxc_init_pcmcia(void) +{ + platform_device_register(&mx31ads_device); +} +#else +static inline void mxc_init_pcmcia(void) +{ +} +#endif + +#if defined(CONFIG_MXC_HMP4E) || defined(CONFIG_MXC_HMP4E_MODULE) +static struct platform_device hmp4e_device = { + .name = "mxc_hmp4e", + .id = 0, + .dev = { + .release = mxc_nop_release, + } }; -static struct resource camera_resources[] = { +static inline void mxc_init_hmp4e(void) +{ + void __iomem *iim_reg = IO_ADDRESS(IIM_BASE_ADDR); + if (cpu_is_mx32()) + return; + + /* override fuse for Hantro HW clock */ + if (__raw_readl(iim_reg + 0x808) == 0x4) { + if (!(__raw_readl(iim_reg + 0x800) & (1 << 5))) { + writel(__raw_readl(iim_reg + 0x808) & 0xfffffffb, + iim_reg + 0x808); + } + } + + platform_device_register(&hmp4e_device); +} +#else +static inline void mxc_init_hmp4e(void) +{ +} +#endif + +static struct platform_device mxc_dma_device = { + .name = "mxc_dma", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, +}; + +static inline void mxc_init_dma(void) +{ + (void)platform_device_register(&mxc_dma_device); +} + +/*! + * Resource definition for the DPTC LP + */ +static struct resource dptc_resources[] = { + [0] = { + .start = CCM_BASE_ADDR, + .end = CCM_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CCM, + .end = MXC_INT_CCM, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for DPTC */ +static struct mxc_dptc_data dptc_data = { + .reg_id = "SW1A", + .clk_id = "cpu_clk", + .dptccr_reg_addr = (unsigned int)MXC_CCM_PMCR0, + .dcvr0_reg_addr = (int)MXC_CCM_DCVR0, + .gpc_cntr_reg_addr = (int)MXC_CCM_PMCR0, + .dptccr = 0xFFFFFFFF, + .dptc_wp_supported = DPTC_WP_SUPPORTED, + .dptc_wp_allfreq = dptc_wp_allfreq_26ckih, + .clk_max_val = 532000000, + .gpc_adu = 0x0, + .vai_mask = MXC_CCM_PMCR0_PTVAI_MASK, + .vai_offset = MXC_CCM_PMCR0_PTVAI_OFFSET, + .dptc_enable_bit = MXC_CCM_PMCR0_DPTEN, + .irq_mask = MXC_CCM_PMCR0_PTVAIM, + .dptc_nvcr_bit = 0x0, + .gpc_irq_bit = 0x00000000, + .init_config = + MXC_CCM_PMCR0_PTVIS | MXC_CCM_PMCR0_DRCE3 | MXC_CCM_PMCR0_DRCE1, + .enable_config = + MXC_CCM_PMCR0_DPTEN | MXC_CCM_PMCR0_DPVCR | MXC_CCM_PMCR0_DPVV, + .dcr_mask = MXC_CCM_PMCR0_DCR, +}; + +/*! Device Definition for MXC DPTC */ +static struct platform_device mxc_dptc_device = { + .name = "mxc_dptc", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &dptc_data, + }, + .num_resources = ARRAY_SIZE(dptc_resources), + .resource = dptc_resources, +}; + +static inline void mxc_init_dptc(void) +{ + if (clk_get_rate(ckih_clk) == 27000000) { + + if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0) + dptc_data.dptc_wp_allfreq = NULL; + else + dptc_data.dptc_wp_allfreq = + dptc_wp_allfreq_27ckih_TO_2_0; + + } else if (clk_get_rate(ckih_clk) == 26000000 + && mxc_cpu_is_rev(CHIP_REV_2_0) == 1) { + dptc_data.dptc_wp_allfreq = dptc_wp_allfreq_26ckih_TO_2_0; + } + + (void)platform_device_register(&mxc_dptc_device); +} + +#ifdef CONFIG_MXC_VPU +static struct resource vpu_resources[] = { { - .start = IPU_CTRL_BASE_ADDR + 0x60, - .end = IPU_CTRL_BASE_ADDR + 0x87, - .flags = IORESOURCE_MEM, - }, + .start = VL2CC_BASE_ADDR, + .end = VL2CC_BASE_ADDR + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, }; -struct platform_device mx3_camera = { - .name = "mx3-camera", - .id = 0, - .num_resources = ARRAY_SIZE(camera_resources), - .resource = camera_resources, - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, +/*! Platform Data for MXC VPU */ +static struct platform_device mxcvpu_device = { + .name = "mxc_vpu", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(vpu_resources), + .resource = vpu_resources, }; -static struct resource otg_resources[] = { +static inline void mxc_init_vpu(void) +{ + if (cpu_is_mx32()) { + if (platform_device_register(&mxcvpu_device) < 0) + printk(KERN_ERR "Error: Registering the VPU.\n"); + } +} +#else +static inline void mxc_init_vpu(void) +{ +} +#endif + +#if defined(CONFIG_HW_RANDOM_FSL_RNGA) || \ +defined(CONFIG_HW_RANDOM_FSL_RNGA_MODULE) +static struct resource rnga_resources[] = { { - .start = OTG_BASE_ADDR, - .end = OTG_BASE_ADDR + 0x1ff, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_USB3, - .end = MXC_INT_USB3, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 otg_dmamask = DMA_BIT_MASK(32); - -/* OTG gadget device */ -struct platform_device mxc_otg_udc_device = { - .name = "fsl-usb2-udc", - .id = -1, - .dev = { - .dma_mask = &otg_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = otg_resources, - .num_resources = ARRAY_SIZE(otg_resources), -}; - -#ifdef CONFIG_ARCH_MX35 -static struct resource mxc_fec_resources[] = { + .start = RNGA_BASE_ADDR, + .end = RNGA_BASE_ADDR + 0x28, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device fsl_rnga_device = { + .name = "fsl_rnga", + .id = -1, + .num_resources = 1, + .resource = rnga_resources, +}; + +static inline void mxc_init_rnga(void) +{ + platform_device_register(&fsl_rnga_device); +} +#else +static inline void mxc_init_rnga(void) +{ +} +#endif + +#if defined(CONFIG_MXC_IIM) || defined(CONFIG_MXC_IIM_MODULE) +static struct resource mxc_iim_resources[] = { { - .start = MXC_FEC_BASE_ADDR, - .end = MXC_FEC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM - }, { - .start = MXC_INT_FEC, - .end = MXC_INT_FEC, - .flags = IORESOURCE_IRQ - }, -}; - -struct platform_device mxc_fec_device = { - .name = "fec", + .start = IIM_BASE_ADDR, + .end = IIM_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mxc_iim_device = { + .name = "mxc_iim", .id = 0, - .num_resources = ARRAY_SIZE(mxc_fec_resources), - .resource = mxc_fec_resources, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(mxc_iim_resources), + .resource = mxc_iim_resources }; -#endif -static int mx3_devices_init(void) +static inline void mxc_init_iim(void) { - if (cpu_is_mx31()) { - mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; - mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; - mxc_register_device(&mxc_rnga_device, NULL); - } - if (cpu_is_mx35()) { - mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; - mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; - } + 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 +int __init mxc_init_devices(void) +{ + mxc_init_wdt(); + mxc_init_ipu(); + mxc_init_spi(); + mxc_init_i2c(); + mxc_init_rtc(); + mxc_init_owire(); + mxc_init_pcmcia(); + mxc_init_scc(); + mxc_init_ssi(); + mxc_init_hmp4e(); + mxc_init_dma(); + mxc_init_audio(); + ckih_clk = clk_get(NULL, "ckih"); + mxc_init_dptc(); + mxc_init_vpu(); + mxc_init_rnga(); + mxc_init_iim(); + + /* SPBA configuration for SSI2 - SDMA and MCU are set */ + spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A); return 0; } - -subsys_initcall(mx3_devices_init); diff --git a/arch/arm/mach-mx3/dma.c b/arch/arm/mach-mx3/dma.c new file mode 100644 index 000000000000..4d63d706cba4 --- /dev/null +++ b/arch/arm/mach-mx3/dma.c @@ -0,0 +1,745 @@ +/* + * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include <linux/init.h> +#include <linux/device.h> +#include <asm/dma.h> +#include <mach/hardware.h> + +#include "serial.h" + +#define MXC_MMC_BUFFER_ACCESS 0x38 +#define MXC_SSI_TX0_REG 0x0 +#define MXC_SSI_TX1_REG 0x4 +#define MXC_SSI_RX0_REG 0x8 +#define MXC_SSI_RX1_REG 0xC +#define MXC_FIRI_TXFIFO 0x14 +#define MXC_SDHC_MMC_WML 16 +#define MXC_SDHC_SD_WML 64 +#define MXC_SSI_TXFIFO_WML 0x4 +#define MXC_SSI_RXFIFO_WML 0x6 +#define MXC_FIRI_WML 16 + +#ifdef CONFIG_SDMA_IRAM +#define trans_type int_2_per +#else +#define trans_type emi_2_per +#endif + +typedef struct mxc_sdma_info_entry_s { + mxc_dma_device_t device; + mxc_sdma_channel_params_t *chnl_info; +} mxc_sdma_info_entry_t; + +static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = { + .chnl_params = { + .watermark_level = UART1_UFCR_RXTL, + .per_address = UART1_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART1_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART1_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = { + .chnl_params = { + .watermark_level = UART1_UFCR_TXTL, + .per_address = UART1_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART1_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART1_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = { + .chnl_params = { + .watermark_level = UART2_UFCR_RXTL, + .per_address = UART2_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART2_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART2_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = { + .chnl_params = { + .watermark_level = UART2_UFCR_TXTL, + .per_address = UART2_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART2_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART2_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = { + .chnl_params = { + .watermark_level = UART3_UFCR_RXTL, + .per_address = UART3_BASE_ADDR, + .peripheral_type = UART_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART3_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART3_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = { + .chnl_params = { + .watermark_level = UART3_UFCR_TXTL, + .per_address = UART3_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART3_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART3_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart4_rx_params = { + .chnl_params = { + .watermark_level = UART4_UFCR_RXTL, + .per_address = UART4_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART4_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART4_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart4_tx_params = { + .chnl_params = { + .watermark_level = UART4_UFCR_TXTL, + .per_address = UART4_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART4_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART4_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart5_rx_params = { + .chnl_params = { + .watermark_level = UART5_UFCR_RXTL, + .per_address = UART5_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART5_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART5_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart5_tx_params = { + .chnl_params = { + .watermark_level = UART5_UFCR_TXTL, + .per_address = UART5_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART5_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART5_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc1_width1_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_MMC_WML, + .per_address = + MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC1, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc1_width4_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_SD_WML, + .per_address = + MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC1, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc2_width1_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_MMC_WML, + .per_address = + MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC2, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc2_width4_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_SD_WML, + .per_address = + MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC2, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = trans_type, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = trans_type, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = trans_type, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = trans_type, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = trans_type, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_fir_rx_params = { + .chnl_params = { + .watermark_level = MXC_FIRI_WML, + .per_address = FIRI_BASE_ADDR, + .peripheral_type = FIRI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_FIRI_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_FIR_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_fir_tx_params = { + .chnl_params = { + .watermark_level = MXC_FIRI_WML, + .per_address = FIRI_BASE_ADDR + MXC_FIRI_TXFIFO, + .peripheral_type = FIRI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_FIRI_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_FIR_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_memory_params = { + .chnl_params = { + .peripheral_type = MEMORY, + .transfer_type = emi_2_emi, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MEMORY, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_fifo_memory_params = { + .chnl_params = { + .peripheral_type = FIFO_MEMORY, + .per_address = MXC_FIFO_MEM_DEST_FIXED, + .transfer_type = emi_2_emi, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + .event_id = 0, + }, + .channel_num = MXC_DMA_CHANNEL_FIFO_MEMORY, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ata_rx_params = { + .chnl_params = { + .watermark_level = MXC_IDE_DMA_WATERMARK, + .per_address = ATA_DMA_BASE_ADDR, + .peripheral_type = ATA, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_ATA_TX_END, + .event_id2 = DMA_REQ_ATA_RX, + .bd_number = MXC_IDE_DMA_BD_NR, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_ATA_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ata_tx_params = { + .chnl_params = { + .watermark_level = MXC_IDE_DMA_WATERMARK, + .per_address = ATA_DMA_BASE_ADDR + 0x18, + .peripheral_type = ATA, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_ATA_TX_END, + .event_id2 = DMA_REQ_ATA_TX, + .bd_number = MXC_IDE_DMA_BD_NR, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_ATA_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; +static mxc_sdma_info_entry_t mxc_sdma_active_dma_info[] = { + {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params}, + {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params}, + {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params}, + {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params}, + {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params}, + {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params}, + {MXC_DMA_UART4_RX, &mxc_sdma_uart4_rx_params}, + {MXC_DMA_UART4_TX, &mxc_sdma_uart4_tx_params}, + {MXC_DMA_UART5_RX, &mxc_sdma_uart5_rx_params}, + {MXC_DMA_UART5_TX, &mxc_sdma_uart5_tx_params}, + {MXC_DMA_MMC1_WIDTH_1, &mxc_sdma_mmc1_width1_params}, + {MXC_DMA_MMC1_WIDTH_4, &mxc_sdma_mmc1_width4_params}, + {MXC_DMA_MMC2_WIDTH_1, &mxc_sdma_mmc2_width1_params}, + {MXC_DMA_MMC2_WIDTH_4, &mxc_sdma_mmc2_width4_params}, + {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params}, + {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params}, + {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params}, + {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params}, + {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params}, + {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params}, + {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params}, + {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params}, + {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params}, + {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params}, + {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params}, + {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params}, + {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params}, + {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params}, + {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params}, + {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params}, + {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params}, + {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params}, + {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params}, + {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params}, + {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params}, + {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params}, + {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params}, + {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params}, + {MXC_DMA_FIR_RX, &mxc_sdma_fir_rx_params}, + {MXC_DMA_FIR_TX, &mxc_sdma_fir_tx_params}, + {MXC_DMA_MEMORY, &mxc_sdma_memory_params}, + {MXC_DMA_FIFO_MEMORY, &mxc_sdma_fifo_memory_params}, + {MXC_DMA_ATA_RX, &mxc_sdma_ata_rx_params}, + {MXC_DMA_ATA_TX, &mxc_sdma_ata_tx_params}, +}; + +static int mxc_sdma_info_entrys = + sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]); + +/*! + * This functions Returns the SDMA paramaters associated for a module + * + * @param channel_id the ID of the module requesting DMA + * @return returns the sdma parameters structure for the device + */ +mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t + channel_id) +{ + mxc_sdma_info_entry_t *p = mxc_sdma_active_dma_info; + int i; + + for (i = 0; i < mxc_sdma_info_entrys; i++, p++) { + if (p->device == channel_id) { + return p->chnl_info; + } + } + return NULL; +} + +/*! + * This functions marks the SDMA channels that are statically allocated + * + * @param chnl the channel array used to store channel information + */ +void mxc_get_static_channels(mxc_dma_channel_t * chnl) +{ +#ifdef CONFIG_SDMA_IRAM + int i; + for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++) + chnl[i].dynamic = 0; +#endif /*CONFIG_SDMA_IRAM */ +} + +EXPORT_SYMBOL(mxc_sdma_get_channel_params); +EXPORT_SYMBOL(mxc_get_static_channels); diff --git a/arch/arm/mach-mx3/dptc.c b/arch/arm/mach-mx3/dptc.c new file mode 100644 index 000000000000..e4fb0bb74df1 --- /dev/null +++ b/arch/arm/mach-mx3/dptc.c @@ -0,0 +1,103 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file dptc.c + * + * @brief DPTC table for the Freescale Semiconductor MXC DPTC module. + * + * @ingroup PM + */ + +#include <mach/hardware.h> +#include <mach/mxc_dptc.h> + +struct dptc_wp dptc_wp_allfreq_26ckih[DPTC_WP_SUPPORTED] = { + /* 532MHz */ + /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */ + /* wp0 */ + {0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000, 1625}, + {0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0, 1600}, + {0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0, 1575}, + {0xffc00000, 0x95e3e8e8, 0xffc00000, 0xe5f70da4, 1550}, + {0xffc00000, 0x9623f8e8, 0xffc00000, 0xe6371da8, 1525}, + /* wp5 */ + {0xffc00000, 0x966408f0, 0xffc00000, 0xe6b73db0, 1500}, + {0xffc00000, 0x96e428f4, 0xffc00000, 0xe7776dbc, 1475}, + {0xffc00000, 0x976448fc, 0xffc00000, 0xe8379dc8, 1450}, + {0xffc00000, 0x97e46904, 0xffc00000, 0xe977ddd8, 1425}, + {0xffc00000, 0x98a48910, 0xffc00000, 0xeab81de8, 1400}, + /* wp10 */ + {0xffc00000, 0x9964b918, 0xffc00000, 0xebf86df8, 1375}, + {0xffc00000, 0xffe4e924, 0xffc00000, 0xfff8ae08, 1350}, + {0xffc00000, 0xffe5192c, 0xffc00000, 0xfff8fe1c, 1350}, + {0xffc00000, 0xffe54938, 0xffc00000, 0xfff95e2c, 1350}, + {0xffc00000, 0xffe57944, 0xffc00000, 0xfff9ae44, 1350}, + /* wp15 */ + {0xffc00000, 0xffe5b954, 0xffc00000, 0xfffa0e58, 1350}, + {0xffc00000, 0xffe5e960, 0xffc00000, 0xfffa6e70, 1350}, +}; + +struct dptc_wp dptc_wp_allfreq_26ckih_TO_2_0[DPTC_WP_SUPPORTED] = { + /* Mx31 TO 2.0 Offset table */ + /* 532MHz */ + /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */ + /* wp0 */ + {0xffc00000, 0x9E265978, 0xffc00000, 0xE4371D9C, 1625}, + {0xffc00000, 0x9E665978, 0xffc00000, 0xE4772D9C, 1600}, + {0xffc00000, 0x9EA65978, 0xffc00000, 0xE4772DA0, 1575}, + {0xffc00000, 0x9EE66978, 0xffc00000, 0xE4B73DA0, 1550}, + {0xffc00000, 0x9F26697C, 0xffc00000, 0xE4F73DA0, 1525}, + /* wp5 */ + {0xffc00000, 0x9F66797C, 0xffc00000, 0xE5774DA4, 1500}, + {0xffc00000, 0x9FE6797C, 0xffc00000, 0xE5F75DA4, 1475}, + {0xffc00000, 0xA026897C, 0xffc00000, 0xE6776DA4, 1450}, + {0xffc00000, 0xA0A6897C, 0xffc00000, 0xE6F77DA8, 1425}, + {0xffc00000, 0xA0E69980, 0xffc00000, 0xE7B78DAC, 1400}, + /* wp10 */ + {0xffc00000, 0xA1669980, 0xffc00000, 0xE8379DAC, 1375}, + {0xffc00000, 0xA1A6A980, 0xffc00000, 0xE8F7ADB0, 1350}, + {0xffc00000, 0xA226B984, 0xffc00000, 0xE9F7CDB0, 1325}, + {0xffc00000, 0xA2A6C984, 0xffc00000, 0xEAB7DDB4, 1300}, + {0xffc00000, 0xA326C988, 0xffc00000, 0xEBB7FDB8, 1275}, + /* wp15 */ + {0xffc00000, 0xA3A6D988, 0xffc00000, 0xECB80DBC, 1250}, + {0xffc00000, 0xA426E988, 0xffc00000, 0xEDB82DC0, 1225}, +}; + +struct dptc_wp dptc_wp_allfreq_27ckih_TO_2_0[DPTC_WP_SUPPORTED] = { + /* Mx31 TO 2.0 Offset table */ + /* 532MHz */ + /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */ + /* wp0 */ + {0xffc00000, 0x9864E920, 0xffc00000, 0xDBB50D1C, 1625}, + {0xffc00000, 0x98A4E920, 0xffc00000, 0xDBF51D1C, 1600}, + {0xffc00000, 0x98E4E920, 0xffc00000, 0xDBF51D20, 1575}, + {0xffc00000, 0x9924F920, 0xffc00000, 0xDC352D20, 1550}, + {0xffc00000, 0x9924F924, 0xffc00000, 0xDC752D20, 1525}, + /* wp5 */ + {0xffc00000, 0x99650924, 0xffc00000, 0xDCF53D24, 1500}, + {0xffc00000, 0x99E50924, 0xffc00000, 0xDD754D24, 1475}, + {0xffc00000, 0x9A251924, 0xffc00000, 0xDDF55D24, 1450}, + {0xffc00000, 0x9AA51924, 0xffc00000, 0xDE756D28, 1425}, + {0xffc00000, 0x9AE52928, 0xffc00000, 0xDF357D2C, 1400}, + /* wp10 */ + {0xffc00000, 0x9B652928, 0xffc00000, 0xDFB58D2C, 1375}, + {0xffc00000, 0x9BA53928, 0xffc00000, 0xE0759D30, 1350}, + {0xffc00000, 0x9C254928, 0xffc00000, 0xE135BD30, 1325}, + {0xffc00000, 0x9CA55928, 0xffc00000, 0xE1F5CD34, 1300}, + {0xffc00000, 0x9D25592C, 0xffc00000, 0xE2F5ED38, 1275}, + /* wp15 */ + {0xffc00000, 0x9DA5692C, 0xffc00000, 0xE3F5FD38, 1250}, + {0xffc00000, 0x9E25792C, 0xffc00000, 0xE4F61D3C, 1225}, +}; diff --git a/arch/arm/mach-mx3/dvfs_v2.c b/arch/arm/mach-mx3/dvfs_v2.c new file mode 100644 index 000000000000..9fa9c7aa5206 --- /dev/null +++ b/arch/arm/mach-mx3/dvfs_v2.c @@ -0,0 +1,535 @@ +/* + * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file dvfs_v2.c + * + * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module. + * + * Upon initialization, the DVFS driver initializes the DVFS hardware + * sets up driver nodes attaches to the DVFS interrupt and initializes internal + * data structures. When the DVFS interrupt occurs the driver checks the cause + * of the interrupt (lower frequency, increase frequency or emergency) and changes + * the CPU voltage according to translation table that is loaded into the driver. + * + * @ingroup PM + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/jiffies.h> +#include <linux/device.h> +#include <linux/sysdev.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/pmic_external.h> +#include <mach/pmic_power.h> + +#include "iomux.h" +#include "crm_regs.h" + +static int dvfs_is_active; + +/* Used for tracking the number of interrupts */ +static u32 dvfs_nr_up[4]; +static u32 dvfs_nr_dn[4]; + +/* + * Clock structures + */ +static struct clk *cpu_clk; +static struct clk *ahb_clk; + +enum { + FSVAI_FREQ_NOCHANGE = 0x0, + FSVAI_FREQ_INCREASE, + FSVAI_FREQ_DECREASE, + FSVAI_FREQ_EMERG, +}; + +/* + * Frequency increase threshold. Increase frequency change request + * will be sent if DVFS counter value will be more than this value. + */ +#define DVFS_UPTHR (30 << MXC_CCM_LTR0_UPTHR_OFFSET) + +/* + * Frequency decrease threshold. Decrease frequency change request + * will be sent if DVFS counter value will be less than this value. + */ +#define DVFS_DNTHR (18 << MXC_CCM_LTR0_DNTHR_OFFSET) + +/* + * With the ARM clocked at 532, this setting yields a DIV_3_CLK of 2.03 kHz. + */ +#define DVFS_DIV3CK (3 << MXC_CCM_LTR0_DIV3CK_OFFSET) + +/* + * DNCNT defines the amount of times the down threshold should be exceeded + * before DVFS will trigger frequency decrease request. + */ +#define DVFS_DNCNT (0x33 << MXC_CCM_LTR1_DNCNT_OFFSET) + +/* + * UPCNT defines the amount of times the up threshold should be exceeded + * before DVFS will trigger frequency increase request. + */ +#define DVFS_UPCNT (0x33 << MXC_CCM_LTR1_UPCNT_OFFSET) + +/* + * Panic threshold. Panic frequency change request + * will be sent if DVFS counter value will be more than this value. + */ +#define DVFS_PNCTHR (63 << MXC_CCM_LTR1_PNCTHR_OFFSET) + +/* + * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add + */ +#define DVFS_LTBRSR (1 << MXC_CCM_LTR1_LTBRSR_OFFSET) + +/* EMAC defines how many samples are included in EMA calculation */ +#define DVFS_EMAC (0x20 << MXC_CCM_LTR2_EMAC_OFFSET) + +const static u8 ltr_gp_weight[] = { + 0, /* 0 */ + 0, + 0, + 0, + 0, + 0, /* 5 */ + 0, + 0, + 0, + 0, + 0, /* 10 */ + 0, + 7, + 7, + 7, + 7, /* 15 */ +}; + +DEFINE_SPINLOCK(mxc_dvfs_lock); + +/*! + * This function sets the weight of general purpose signals + * @param gp_id number of general purpose bit + * @param weight the weight of the general purpose bit + */ +static void set_gp_weight(int gp_id, u8 weight) +{ + u32 reg; + + if (gp_id < 9) { + reg = __raw_readl(MXC_CCM_LTR3); + reg = (reg & ~(MXC_CCM_LTR3_WSW_MASK(gp_id))) | + (weight << MXC_CCM_LTR3_WSW_OFFSET(gp_id)); + __raw_writel(reg, MXC_CCM_LTR3); + } else if (gp_id < 16) { + reg = __raw_readl(MXC_CCM_LTR2); + reg = (reg & ~(MXC_CCM_LTR2_WSW_MASK(gp_id))) | + (weight << MXC_CCM_LTR2_WSW_OFFSET(gp_id)); + __raw_writel(reg, MXC_CCM_LTR2); + } +} + +static int start_dvfs(void) +{ + u32 reg; + unsigned long flags; + + if (dvfs_is_active) { + return 0; + } + + spin_lock_irqsave(&mxc_dvfs_lock, flags); + + reg = __raw_readl(MXC_CCM_PMCR0); + + /* enable dvfs and interrupt */ + reg = (reg & ~MXC_CCM_PMCR0_FSVAIM) | MXC_CCM_PMCR0_DVFEN; + + __raw_writel(reg, MXC_CCM_PMCR0); + + dvfs_is_active = 1; + + spin_unlock_irqrestore(&mxc_dvfs_lock, flags); + + pr_info("DVFS is started\n"); + + return 0; +} + +#define MXC_CCM_LTR0_CONFIG_MASK (MXC_CCM_LTR0_UPTHR_MASK | \ + MXC_CCM_LTR0_DNTHR_MASK | \ + MXC_CCM_LTR0_DIV3CK_MASK) +#define MXC_CCM_LTR0_CONFIG_VAL (DVFS_UPTHR | DVFS_DNTHR | DVFS_DIV3CK) + +#define MXC_CCM_LTR1_CONFIG_MASK (MXC_CCM_LTR1_UPCNT_MASK | \ + MXC_CCM_LTR1_DNCNT_MASK | \ + MXC_CCM_LTR1_PNCTHR_MASK | \ + MXC_CCM_LTR1_LTBRSR_MASK) +#define MXC_CCM_LTR1_CONFIG_VAL (DVFS_UPCNT | DVFS_DNCNT | \ + DVFS_PNCTHR | DVFS_LTBRSR) + +/*! + * This function is called for module initialization. + * It sets up the DVFS hardware. + * It sets default values for DVFS thresholds and counters. The default + * values was chosen from a set of different reasonable values. They was tested + * and the default values in the driver gave the best results. + * More work should be done to find optimal values. + * + * @return 0 if successful; non-zero otherwise. + * + */ +static int init_dvfs_controller(void) +{ + u32 i, reg; + + /* Configure 2 MC13783 DVFS pins */ + mxc_request_iomux(MX31_PIN_DVFS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_DVFS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_NONE); + + /* Configure MC13783 voltage ready input pin */ + mxc_request_iomux(MX31_PIN_GPIO1_5, OUTPUTCONFIG_GPIO, + INPUTCONFIG_FUNC); + + /* setup LTR0 */ + reg = __raw_readl(MXC_CCM_LTR0); + reg = (reg & ~(MXC_CCM_LTR0_CONFIG_MASK)) | MXC_CCM_LTR0_CONFIG_VAL; + __raw_writel(reg, MXC_CCM_LTR0); + + /* set up LTR1 */ + reg = __raw_readl(MXC_CCM_LTR1); + reg = (reg & ~(MXC_CCM_LTR1_CONFIG_MASK)) | MXC_CCM_LTR1_CONFIG_VAL; + __raw_writel(reg, MXC_CCM_LTR1); + + /* setup LTR2 */ + reg = __raw_readl(MXC_CCM_LTR2); + reg = (reg & ~(MXC_CCM_LTR2_EMAC_MASK)) | DVFS_EMAC; + __raw_writel(reg, MXC_CCM_LTR2); + + /* Set general purpose weights to 0 */ + for (i = 0; i < 16; i++) { + set_gp_weight(i, ltr_gp_weight[i]); + } + + /* ARM interrupt, mask load buf full interrupt */ + reg = __raw_readl(MXC_CCM_PMCR0); + reg |= MXC_CCM_PMCR0_DVFIS | MXC_CCM_PMCR0_LBMI; + __raw_writel(reg, MXC_CCM_PMCR0); + + /* configuring EMI Handshake and PLL relock disable */ + reg = __raw_readl(MXC_CCM_PMCR1); + reg |= MXC_CCM_PMCR1_PLLRDIS; + reg |= MXC_CCM_PMCR1_EMIRQ_EN; + __raw_writel(reg, MXC_CCM_PMCR1); + + return 0; +} + +static irqreturn_t dvfs_irq(int irq, void *dev_id) +{ + u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); + u32 fsvai = (pmcr0 & MXC_CCM_PMCR0_FSVAI_MASK) >> + MXC_CCM_PMCR0_FSVAI_OFFSET; + u32 dvsup = (pmcr0 & MXC_CCM_PMCR0_DVSUP_MASK) >> + MXC_CCM_PMCR0_DVSUP_OFFSET; + u32 curr_ahb, curr_cpu, rate; + + /* Should not be here if FSVAIM is set */ + BUG_ON(pmcr0 & MXC_CCM_PMCR0_FSVAIM); + + if (fsvai == FSVAI_FREQ_NOCHANGE) { + /* Do nothing. Freq change is not required */ + printk(KERN_WARNING "fsvai should not be 0\n"); + return IRQ_HANDLED; + } + + if (!(pmcr0 & MXC_CCM_PMCR0_UPDTEN)) { + /* Do nothing. DVFS didn't finish previous flow update */ + return IRQ_HANDLED; + } + + if (((dvsup == DVSUP_LOW) && (fsvai == FSVAI_FREQ_DECREASE)) || + ((dvsup == DVSUP_TURBO) && ((fsvai == FSVAI_FREQ_INCREASE) || + (fsvai == FSVAI_FREQ_EMERG)))) { + /* Interrupt should be disabled in these cases according to + * the spec since DVFS is already at lowest (highest) state */ + printk(KERN_WARNING "Something is wrong?\n"); + return IRQ_HANDLED; + } + + curr_ahb = clk_get_rate(ahb_clk); + if (fsvai == FSVAI_FREQ_DECREASE) { + curr_cpu = clk_get_rate(cpu_clk); + rate = ((curr_cpu / curr_ahb) - 1) * curr_ahb; + if ((cpu_is_mx31_rev(CHIP_REV_2_0) < 0) && + ((curr_cpu / curr_ahb) == 4)) { + rate = ((curr_cpu / curr_ahb) - 2) * curr_ahb; + } + dvfs_nr_dn[dvsup]++; + } else { + rate = 4 * curr_ahb; + dvfs_nr_up[dvsup]++; + } + + clk_set_rate(cpu_clk, rate); + return IRQ_HANDLED; +} + +/*! + * This function disables the DVFS module. + */ +static void stop_dvfs(void) +{ + u32 pmcr0, dvsup; + unsigned long flags; + u32 curr_ahb = clk_get_rate(ahb_clk); + + if (dvfs_is_active) { + spin_lock_irqsave(&mxc_dvfs_lock, flags); + + pmcr0 = __raw_readl(MXC_CCM_PMCR0); + dvsup = (pmcr0 & MXC_CCM_PMCR0_DVSUP_MASK) >> + MXC_CCM_PMCR0_DVSUP_OFFSET; + if (dvsup != DVSUP_TURBO) { + /* Use sw delay to insure volt/freq change */ + clk_set_rate(cpu_clk, (4 * curr_ahb)); + udelay(200); + } + + pmcr0 = __raw_readl(MXC_CCM_PMCR0); + /* disable dvfs and its interrupt */ + pmcr0 = (pmcr0 & ~MXC_CCM_PMCR0_DVFEN) | MXC_CCM_PMCR0_FSVAIM; + __raw_writel(pmcr0, MXC_CCM_PMCR0); + + dvfs_is_active = 0; + + spin_unlock_irqrestore(&mxc_dvfs_lock, flags); + } + + pr_info("DVFS is stopped\n"); +} + +void pmic_voltage_init(void) +{ + t_regulator_voltage volt; + + /* Enable 4 mc13783 output voltages */ + pmic_write_reg(REG_ARBITRATION_SWITCHERS, (1 << 5), (1 << 5)); + + /* Set mc13783 DVS speed 25mV each 4us */ + pmic_write_reg(REG_SWITCHERS_4, (0 << 6), (3 << 6)); + + if (cpu_is_mx31()) + volt.sw1a = SW1A_1_625V; + else + volt.sw1a = SW1A_1_425V; + + pmic_power_regulator_set_voltage(SW_SW1A, volt); + + volt.sw1a = SW1A_1_25V; + pmic_power_switcher_set_dvs(SW_SW1A, volt); + + if (cpu_is_mx32()) { + volt.sw1a = SW1A_0_975V; + pmic_power_switcher_set_stby(SW_SW1A, volt); + } + + volt.sw1b = SW1A_1_25V; + pmic_power_switcher_set_dvs(SW_SW1B, volt); + + volt.sw1b = SW1A_1_25V; + pmic_power_switcher_set_stby(SW_SW1B, volt); +} + +static ssize_t dvfs_enable_store(struct sys_device *dev, struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + if (strstr(buf, "1") != NULL) { + if (start_dvfs() != 0) { + printk(KERN_ERR "Failed to start DVFS\n"); + } + } else if (strstr(buf, "0") != NULL) { + stop_dvfs(); + } + + return size; +} + +static ssize_t dvfs_status_show(struct sys_device *dev, struct sysdev_attribute *attr, + char *buf) +{ + int size = 0; + + if (dvfs_is_active) { + size = sprintf(buf, "DVFS is enabled\n"); + } else { + size = sprintf(buf, "DVFS is disabled\n"); + } + size += + sprintf((buf + size), "UP:\t%d\t%d\t%d\t%d\n", dvfs_nr_up[0], + dvfs_nr_up[1], dvfs_nr_up[2], dvfs_nr_up[3]); + size += + sprintf((buf + size), "DOWN:\t%d\t%d\t%d\t%d\n\n", dvfs_nr_dn[0], + dvfs_nr_dn[1], dvfs_nr_dn[2], dvfs_nr_dn[3]); + + return size; +} + +static ssize_t dvfs_status_store(struct sys_device *dev, struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + if (strstr(buf, "reset") != NULL) { + int i; + for (i = 0; i < 4; i++) { + dvfs_nr_up[i] = 0; + dvfs_nr_dn[i] = 0; + } + } + + return size; +} + +static ssize_t dvfs_debug_show(struct sys_device *dev, struct sysdev_attribute *attr, + char *buf) +{ + int size = 0; + u32 curr_ahb, curr_cpu; + + curr_ahb = clk_get_rate(ahb_clk); + curr_cpu = clk_get_rate(cpu_clk); + + pr_debug("ahb %d, cpu %d\n", curr_ahb, curr_cpu); + + return size; +} + +static ssize_t dvfs_debug_store(struct sys_device *dev, struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + u32 curr_ahb, curr_cpu, rate = 0; + + curr_ahb = clk_get_rate(ahb_clk); + curr_cpu = clk_get_rate(cpu_clk); + + if (strstr(buf, "inc") != NULL) { + rate = 4 * curr_ahb; + pr_debug("inc to %d\n", rate); + } + + if (strstr(buf, "dec") != NULL) { + rate = ((curr_cpu / curr_ahb) - 1) * curr_ahb; + if ((cpu_is_mx31_rev(CHIP_REV_2_0) < 0) && + ((curr_cpu / curr_ahb) == 4)) + rate = ((curr_cpu / curr_ahb) - 2) * curr_ahb; + + pr_debug("dec to %d\n", rate); + } + + clk_set_rate(cpu_clk, rate); + + return size; +} + +static SYSDEV_ATTR(enable, 0200, NULL, dvfs_enable_store); +static SYSDEV_ATTR(status, 0644, dvfs_status_show, dvfs_status_store); +static SYSDEV_ATTR(debug, 0644, dvfs_debug_show, dvfs_debug_store); + +static struct sysdev_class dvfs_sysclass = { + .name = "dvfs", +}; + +static struct sys_device dvfs_device = { + .id = 0, + .cls = &dvfs_sysclass, +}; + +static int dvfs_sysdev_ctrl_init(void) +{ + int err; + + err = sysdev_class_register(&dvfs_sysclass); + if (!err) + err = sysdev_register(&dvfs_device); + if (!err) { + err = sysdev_create_file(&dvfs_device, &attr_enable); + err = sysdev_create_file(&dvfs_device, &attr_status); + err = sysdev_create_file(&dvfs_device, &attr_debug); + } + + return err; +} + +static void dvfs_sysdev_ctrl_exit(void) +{ + sysdev_remove_file(&dvfs_device, &attr_enable); + sysdev_remove_file(&dvfs_device, &attr_status); + sysdev_unregister(&dvfs_device); + sysdev_class_unregister(&dvfs_sysclass); +} + +static int __init dvfs_init(void) +{ + int err = 0; + pmic_voltage_init(); + + cpu_clk = clk_get(NULL, "cpu_clk"); + ahb_clk = clk_get(NULL, "ahb_clk"); + err = init_dvfs_controller(); + if (err) { + printk(KERN_ERR "DVFS: Unable to initialize DVFS"); + return err; + } + + /* request the DVFS interrupt */ + err = request_irq(MXC_INT_CCM_DVFS, dvfs_irq, IRQF_DISABLED, "dvfs", NULL); + if (err) { + printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt"); + } + + err = dvfs_sysdev_ctrl_init(); + if (err) { + printk(KERN_ERR + "DVFS: Unable to register sysdev entry for dvfs"); + return err; + } + + return err; +} + +static void __exit dvfs_cleanup(void) +{ + stop_dvfs(); + + /* release the DVFS interrupt */ + free_irq(MXC_INT_CCM_DVFS, NULL); + + dvfs_sysdev_ctrl_exit(); + + clk_put(cpu_clk); + clk_put(ahb_clk); +} + +module_init(dvfs_init); +module_exit(dvfs_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("DVFS driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c index c66ccbcdc11b..9f6841ec2fdf 100644 --- a/arch/arm/mach-mx3/iomux.c +++ b/arch/arm/mach-mx3/iomux.c @@ -1,181 +1,260 @@ /* - * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> - * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch> + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup GPIO_MX31 Board GPIO and Muxing Setup + * @ingroup MSL_MX31 + */ +/*! + * @file mach-mx3/iomux.c * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * @brief I/O Muxing control functions * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. + * @ingroup GPIO_MX31 */ +#include <linux/io.h> #include <linux/module.h> #include <linux/spinlock.h> -#include <linux/io.h> -#include <linux/kernel.h> #include <mach/hardware.h> #include <mach/gpio.h> -#include <mach/iomux-mx3.h> +#include "iomux.h" -/* - * IOMUX register (base) addresses +/*! + * 4 control fields per MUX register */ -#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) -#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000) -#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004) -#define IOMUXGPR (IOMUX_BASE + 0x008) -#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C) -#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154) +#define MUX_CTL_FIELDS 4 -static DEFINE_SPINLOCK(gpio_mux_lock); +/*! + * 3 control fields per PAD register + */ +#define PAD_CTL_FIELDS 3 -#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) +/*! + * Maximum number of MUX pins + * Number of pins = (highest iomux reg - lowest iomux reg + 1) * (4 pins/reg) + */ +#define MUX_PIN_NUM_MAX \ + (((u32 *)IOMUXSW_MUX_END - (u32 *)IOMUXSW_MUX_CTL + 1) * MUX_CTL_FIELDS) -unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; -/* - * set the mode for a IOMUX pin. +/*! + * Number of pad controls = + * (highest pad ctl reg - lowest pad ctl reg + 1) * (3 pins/reg) */ -int mxc_iomux_mode(unsigned int pin_mode) -{ - u32 field, l, mode, ret = 0; - void __iomem *reg; +#define PAD_CTL_NUM_MAX \ + (((u32 *)IOMUXSW_PAD_END - (u32 *)IOMUXSW_PAD_CTL + 1) * PAD_CTL_FIELDS) - reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK); - field = pin_mode & 0x3; - mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; +#define PIN_TO_IOMUX_INDEX(pin) ((pin >> MUX_I) & ((1 << (MUX_F - MUX_I)) - 1)) +#define PIN_TO_IOMUX_FIELD(pin) ((pin >> MUX_F) & ((1 << (PAD_I - MUX_F)) - 1)) - spin_lock(&gpio_mux_lock); +/*! + * 8 bits for each MUX control field + */ +#define MUX_CTL_BIT_LEN 8 - l = __raw_readl(reg); - l &= ~(0xff << (field * 8)); - l |= mode << (field * 8); - __raw_writel(l, reg); +/*! + * 10 bits for each PAD control field + */ +#define MUX_PAD_BIT_LEN 10 - spin_unlock(&gpio_mux_lock); +/*! + * IOMUX register (base) addresses + */ +#define IOMUXGPR (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x008) /*!< General purpose */ +#define IOMUXSW_MUX_CTL (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x00C) /*!< MUX control */ +#define IOMUXSW_MUX_END (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x150) /*!< last MUX control register */ +#define IOMUXSW_PAD_CTL (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x154) /*!< Pad control */ +#define IOMUXSW_PAD_END (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x308) /*!< last Pad control register */ +#define IOMUXINT_OBS1 (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x000) /*!< Observe interrupts 1 */ +#define IOMUXINT_OBS2 (IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004) /*!< Observe interrupts 2 */ - return ret; -} -EXPORT_SYMBOL(mxc_iomux_mode); +/* len - mask bit length; fld - mask bit field. Example, to have the mask: + * 0xFF000000, use GET_FIELD_MASK(8, 3). Translate in plain language: + * "set the 3rd (0-based) 8-bit-long field to all 1's */ +#define GET_FIELD_MASK(len, fld) (((1 << len) - 1) << (len * fld)) +static DEFINE_SPINLOCK(gpio_mux_lock); +static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX]; -/* - * This function configures the pad value for a IOMUX pin. +/*! + * This function is used to configure a pin through the IOMUX module. + * FIXED ME: for backward compatible. Will be static function! + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + * + * @return 0 if successful; Non-zero otherwise */ -void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) +int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in) { - u32 field, l; void __iomem *reg; + u32 l, ret = 0; + u32 mux_index = PIN_TO_IOMUX_INDEX(pin); + u32 mux_field = PIN_TO_IOMUX_FIELD(pin); + u32 mux_mask = GET_FIELD_MASK(MUX_CTL_BIT_LEN, mux_field); + u8 *rp; - pin &= IOMUX_PADNUM_MASK; - reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4; - field = (pin + 2) % 3; - - pr_debug("%s: reg offset = 0x%x, field = %d\n", - __func__, (pin + 2) / 3, field); + BUG_ON((mux_index > (MUX_PIN_NUM_MAX / MUX_CTL_FIELDS - 1)) || + (mux_field >= MUX_CTL_FIELDS)); + reg = IOMUXSW_MUX_CTL + (mux_index * 4); spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); - l &= ~(0x1ff << (field * 10)); - l |= config << (field * 10); + l = (l & (~mux_mask)) | + (((out << 4) | in) << (mux_field * MUX_CTL_BIT_LEN)); __raw_writel(l, reg); - + /* + * Log a warning if a pin changes ownership + */ + rp = iomux_pin_res_table + mux_index * MUX_CTL_FIELDS + mux_field; + if (out & *rp && *rp != ((out << 4) | in)) { + /* + * Don't call printk if we're tweaking the console uart or + * we'll deadlock. + */ + if (pin != MX31_PIN_CTS1 && + pin != MX31_PIN_RTS1 && + pin != MX31_PIN_DCD_DCE1 && + pin != MX31_PIN_DSR_DTE1 && + pin != MX31_PIN_DTR_DTE1 && + pin != MX31_PIN_RI_DCE1 && + pin != MX31_PIN_DSR_DCE1 && + pin != MX31_PIN_DTR_DCE1 && + pin != MX31_PIN_RXD1 && pin != MX31_PIN_TXD1) { + printk(KERN_ERR "iomux_config_mux: Warning: iomux pin" + " config changed, index=%d field=%d, " + " prev=0x%x new=0x%x\n", mux_index, mux_field, + *rp, (out << 4) | in); + } + ret = -EINVAL; + } + *rp = (out << 4) | in; spin_unlock(&gpio_mux_lock); + + return ret; } -EXPORT_SYMBOL(mxc_iomux_set_pad); -/* - * allocs a single pin: - * - reserves the pin so that it is not claimed by another driver - * - setups the iomux according to the configuration +/*! + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by \b iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + * + * @return 0 if successful; Non-zero otherwise */ -int mxc_iomux_alloc_pin(const unsigned int pin, const char *label) +int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in) { - unsigned pad = pin & IOMUX_PADNUM_MASK; - - if (pad >= (PIN_MAX + 1)) { - printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n", - pad, label ? label : "?"); - return -EINVAL; - } - - if (test_and_set_bit(pad, mxc_pin_alloc_map)) { - printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", - pad, label ? label : "?"); - return -EBUSY; + int ret = iomux_config_mux(pin, out, in); + if (out == OUTPUTCONFIG_GPIO && in == INPUTCONFIG_GPIO) { + ret |= gpio_request(IOMUX_TO_GPIO(pin), NULL); } - mxc_iomux_mode(pin); - - return 0; + return ret; } -EXPORT_SYMBOL(mxc_iomux_alloc_pin); -int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, - const char *label) +/*! + * Release ownership for an IO pin + * + * @param pin a name defined by \b iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in) { - unsigned int *p = pin_list; - int i; - int ret = -EINVAL; - - for (i = 0; i < count; i++) { - ret = mxc_iomux_alloc_pin(*p, label); - if (ret) - goto setup_error; - p++; - } - return 0; + u32 mux_index = PIN_TO_IOMUX_INDEX(pin); + u32 mux_field = PIN_TO_IOMUX_FIELD(pin); + u8 *rp = iomux_pin_res_table + mux_index * MUX_CTL_FIELDS + mux_field; -setup_error: - mxc_iomux_release_multiple_pins(pin_list, i); - return ret; + BUG_ON((mux_index > (MUX_PIN_NUM_MAX / MUX_CTL_FIELDS - 1)) || + (mux_field >= MUX_CTL_FIELDS)); + + *rp = 0; + if (out == OUTPUTCONFIG_GPIO && in == INPUTCONFIG_GPIO) { + gpio_free(IOMUX_TO_GPIO(pin)); + } } -EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins); -void mxc_iomux_release_pin(const unsigned int pin) +/*! + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param config the ORed value of elements defined in \b #iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) { - unsigned pad = pin & IOMUX_PADNUM_MASK; + void __iomem *reg; + u32 l; + u32 pad_index = (pin >> PAD_I) & ((1 << (PAD_F - PAD_I)) - 1); + u32 pad_field = (pin >> PAD_F) & ((1 << (MUX_IO_I - PAD_F)) - 1); + u32 pad_mask = GET_FIELD_MASK(MUX_PAD_BIT_LEN, pad_field); - if (pad < (PIN_MAX + 1)) - clear_bit(pad, mxc_pin_alloc_map); + BUG_ON((pad_index > (PAD_CTL_NUM_MAX / PAD_CTL_FIELDS - 1)) || + (pad_field >= PAD_CTL_FIELDS)); + + reg = IOMUXSW_PAD_CTL + (pad_index * 4); + spin_lock(&gpio_mux_lock); + l = __raw_readl(reg); + l = (l & (~pad_mask)) | (config << (pad_field * MUX_PAD_BIT_LEN)); + __raw_writel(l, reg); + spin_unlock(&gpio_mux_lock); } -EXPORT_SYMBOL(mxc_iomux_release_pin); -void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count) +/* + * FIXED ME: for backward compatible. to be removed! + */ +void iomux_config_pad(iomux_pin_name_t pin, u32 config) { - unsigned int *p = pin_list; - int i; - - for (i = 0; i < count; i++) { - mxc_iomux_release_pin(*p); - p++; - } + mxc_iomux_set_pad(pin, config); } -EXPORT_SYMBOL(mxc_iomux_release_multiple_pins); -/* +/*! * This function enables/disables the general purpose function for a particular * signal. + * + * @param gp one signal as defined in \b #iomux_gp_func_t + * @param en \b #true to enable; \b #false to disable */ -void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) +void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en) { u32 l; spin_lock(&gpio_mux_lock); l = __raw_readl(IOMUXGPR); - if (en) + if (en) { l |= gp; - else + } else { l &= ~gp; - + } __raw_writel(l, IOMUXGPR); spin_unlock(&gpio_mux_lock); } + +/*! + * FIXED ME: for backward compatible. to be removed! + */ +void iomux_config_gpr(iomux_gp_func_t gp, bool en) +{ + mxc_iomux_set_gpr(gp, en); +} + +EXPORT_SYMBOL(mxc_request_iomux); +EXPORT_SYMBOL(mxc_free_iomux); +EXPORT_SYMBOL(mxc_iomux_set_pad); EXPORT_SYMBOL(mxc_iomux_set_gpr); +EXPORT_SYMBOL(iomux_config_pad); +EXPORT_SYMBOL(iomux_config_gpr); +EXPORT_SYMBOL(iomux_config_mux); diff --git a/arch/arm/mach-mx3/iomux.h b/arch/arm/mach-mx3/iomux.h new file mode 100644 index 000000000000..194e091ec656 --- /dev/null +++ b/arch/arm/mach-mx3/iomux.h @@ -0,0 +1,186 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __MACH_MX31_IOMUX_H__ +#define __MACH_MX31_IOMUX_H__ + +#include <linux/types.h> +#include <mach/gpio.h> +#include "mx31_pins.h" + +typedef unsigned int iomux_pin_name_t; +/*! + * @file mach-mx3/iomux.h + * + * @brief I/O Muxing control definitions and functions + * + * @ingroup GPIO_MX31 + */ + +/*! + * various IOMUX output functions + */ +typedef enum iomux_output_config { + OUTPUTCONFIG_GPIO = 0, /*!< used as GPIO */ + OUTPUTCONFIG_FUNC, /*!< used as function */ + OUTPUTCONFIG_ALT1, /*!< used as alternate function 1 */ + OUTPUTCONFIG_ALT2, /*!< used as alternate function 2 */ + OUTPUTCONFIG_ALT3, /*!< used as alternate function 3 */ + OUTPUTCONFIG_ALT4, /*!< used as alternate function 4 */ + OUTPUTCONFIG_ALT5, /*!< used as alternate function 5 */ + OUTPUTCONFIG_ALT6 /*!< used as alternate function 6 */ +} iomux_pin_ocfg_t; + +/*! + * various IOMUX input functions + */ +typedef enum iomux_input_config { + INPUTCONFIG_NONE = 0, /*!< not configured for input */ + INPUTCONFIG_GPIO = 1 << 0, /*!< used as GPIO */ + INPUTCONFIG_FUNC = 1 << 1, /*!< used as function */ + INPUTCONFIG_ALT1 = 1 << 2, /*!< used as alternate function 1 */ + INPUTCONFIG_ALT2 = 1 << 3 /*!< used as alternate function 2 */ +} iomux_pin_icfg_t; + +/*! + * various IOMUX pad functions + */ +typedef enum iomux_pad_config { + PAD_CTL_NOLOOPBACK = 0x0 << 9, + PAD_CTL_LOOPBACK = 0x1 << 9, + PAD_CTL_PKE_NONE = 0x0 << 8, + PAD_CTL_PKE_ENABLE = 0x1 << 8, + PAD_CTL_PUE_KEEPER = 0x0 << 7, + PAD_CTL_PUE_PUD = 0x1 << 7, + PAD_CTL_100K_PD = 0x0 << 5, + PAD_CTL_100K_PU = 0x1 << 5, + PAD_CTL_47K_PU = 0x2 << 5, + PAD_CTL_22K_PU = 0x3 << 5, + PAD_CTL_HYS_CMOS = 0x0 << 4, + PAD_CTL_HYS_SCHMITZ = 0x1 << 4, + PAD_CTL_ODE_CMOS = 0x0 << 3, + PAD_CTL_ODE_OpenDrain = 0x1 << 3, + PAD_CTL_DRV_NORMAL = 0x0 << 1, + PAD_CTL_DRV_HIGH = 0x1 << 1, + PAD_CTL_DRV_MAX = 0x2 << 1, + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0 +} iomux_pad_config_t; + +/*! + * various IOMUX general purpose functions + */ +typedef enum iomux_gp_func { + MUX_PGP_FIRI = 0x1 << 0, + MUX_DDR_MODE = 0x1 << 1, + MUX_PGP_CSPI_BB = 0x1 << 2, + MUX_PGP_ATA_1 = 0x1 << 3, + MUX_PGP_ATA_2 = 0x1 << 4, + MUX_PGP_ATA_3 = 0x1 << 5, + MUX_PGP_ATA_4 = 0x1 << 6, + MUX_PGP_ATA_5 = 0x1 << 7, + MUX_PGP_ATA_6 = 0x1 << 8, + MUX_PGP_ATA_7 = 0x1 << 9, + MUX_PGP_ATA_8 = 0x1 << 10, + MUX_PGP_UH2 = 0x1 << 11, + MUX_SDCTL_CSD0_SEL = 0x1 << 12, + MUX_SDCTL_CSD1_SEL = 0x1 << 13, + MUX_CSPI1_UART3 = 0x1 << 14, + MUX_EXTDMAREQ2_MBX_SEL = 0x1 << 15, + MUX_TAMPER_DETECT_EN = 0x1 << 16, + MUX_PGP_USB_4WIRE = 0x1 << 17, + MUX_PGB_USB_COMMON = 0x1 << 18, + MUX_SDHC_MEMSTICK1 = 0x1 << 19, + MUX_SDHC_MEMSTICK2 = 0x1 << 20, + MUX_PGP_SPLL_BYP = 0x1 << 21, + MUX_PGP_UPLL_BYP = 0x1 << 22, + MUX_PGP_MSHC1_CLK_SEL = 0x1 << 23, + MUX_PGP_MSHC2_CLK_SEL = 0x1 << 24, + MUX_CSPI3_UART5_SEL = 0x1 << 25, + MUX_PGP_ATA_9 = 0x1 << 26, + MUX_PGP_USB_SUSPEND = 0x1 << 27, + MUX_PGP_USB_OTG_LOOPBACK = 0x1 << 28, + MUX_PGP_USB_HS1_LOOPBACK = 0x1 << 29, + MUX_PGP_USB_HS2_LOOPBACK = 0x1 << 30, + MUX_CLKO_DDR_MODE = 0x1 << 31, +} iomux_gp_func_t; + +/*! + * This function is used to configure a pin through the IOMUX module. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + * @return 0 if successful; Non-zero otherwise + */ +int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in); + +/*! + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pins + * @param config ORed value of elements defined in \b #iomux_pad_config_t + */ +void iomux_config_pad(iomux_pin_name_t pin, __u32 config); + +/*! + * This function enables/disables the general purpose function for a particular + * signal. + * + * @param gp one signal as defined in \b #iomux_gp_func_t + * @param en \b #true to enable; \b #false to disable + */ +void iomux_config_gpr(iomux_gp_func_t gp, bool en); + +/*! + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by \b iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in); + +/*! + * Release ownership for an IO pin + * + * @param pin a name defined by \b iomux_pin_name_t + * @param out an output function as defined in \b #iomux_pin_ocfg_t + * @param in an input function as defined in \b #iomux_pin_icfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out, + iomux_pin_icfg_t in); + +/*! + * This function enables/disables the general purpose function for a particular + * signal. + * + * @param gp one signal as defined in \b #iomux_gp_func_t + * @param en \b #true to enable; \b #false to disable + */ +void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en); + +/*! + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param config the ORed value of elements defined in \b #iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config); + +#endif diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index 1f5fdd456cb9..de000f01a193 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c @@ -30,7 +30,6 @@ #include <mach/common.h> #include <mach/hardware.h> - /*! * @file mm.c * @@ -43,7 +42,7 @@ * This table defines static virtual address mappings for I/O regions. * These are the mappings common across all MX3 boards. */ -static struct map_desc mxc_io_desc[] __initdata = { +static struct map_desc mx31_io_desc[] __initdata = { { .virtual = X_MEMC_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR), @@ -64,6 +63,16 @@ static struct map_desc mxc_io_desc[] __initdata = { .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), .length = AIPS2_SIZE, .type = MT_DEVICE_NONSHARED + }, { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_DEVICE_NONSHARED + }, { + .virtual = MX31_IRAM_BASE_ADDR_VIRT & 0xFFF00000, + .pfn = __phys_to_pfn(MX31_IRAM_BASE_ADDR & 0xFFF00000), + .length = SZ_1M, + .type = MT_DEVICE_NONSHARED }, }; @@ -76,14 +85,7 @@ void __init mx31_map_io(void) { mxc_set_cpu_type(MXC_CPU_MX31); - iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); -} - -void __init mx35_map_io(void) -{ - mxc_set_cpu_type(MXC_CPU_MX35); - - iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); + iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc)); } #ifdef CONFIG_CACHE_L2X0 diff --git a/arch/arm/mach-mx3/mx31_pins.h b/arch/arm/mach-mx3/mx31_pins.h new file mode 100644 index 000000000000..2e2274922069 --- /dev/null +++ b/arch/arm/mach-mx3/mx31_pins.h @@ -0,0 +1,429 @@ +/* + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_MXC_MX31_PINS_H__ +#define __ASM_ARCH_MXC_MX31_PINS_H__ + +/*! + * @file arch-mxc/mx31_pins.h + * + * @brief MX31 I/O Pin List + * + * @ingroup GPIO_MX31 + */ + +#ifndef __ASSEMBLY__ + +/*! + * @name IOMUX/PAD Bit field definitions + */ + +/*! @{ */ + +/*! + * In order to identify pins more effectively, each mux-controlled pin's + * enumerated value is constructed in the following way: + * + * ------------------------------------------------------------------- + * 31-29 | 28 - 24 |23 - 21| 20 | 19 - 18 | 17 - 10| 9 - 8 | 7 - 0 + * ------------------------------------------------------------------- + * IO_P | IO_I | RSVD | PAD_F | PAD_I | MUX_F | MUX_I + * ------------------------------------------------------------------- + * + * Bit 0 to 7 contains MUX_I used to identify the register + * offset (0-based. base is IOMUX_module_base + 0xC) defined in the Section + * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. Bit 8 to 9 is MUX_F which + * contains the offset value defined WITHIN the same register (each IOMUX + * control register contains four 8-bit fields for four different pins). The + * similar field definitions are used for the pad control register. + * For example, the MX31_PIN_A0 is defined in the enumeration: + * ( 73 << MUX_I) | (0 << MUX_F)|( 98 << PAD_I) | (0 << PAD_F) + * It means the mux control register is at register offset 73. So the absolute + * address is: 0xC+73*4=0x130 0 << MUX_F means the control bits are at the + * least significant bits within the register. The pad control register offset + * is: 0x154+98*4=0x2DC and also occupy the least significant bits within the + * register. + */ + +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * MUX control register index (0-based) + */ +#define MUX_I 0 + +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * field within IOMUX control register for control bits + * (legal values are 0, 1, 2, 3) + */ +#define MUX_F 8 + +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * PAD control register index (0-based) + */ +#define PAD_I 10 + +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * field within PAD control register for control bits + * (legal values are 0, 1, 2) + */ +#define PAD_F 18 + +#define _MXC_BUILD_PIN(gp,gi,mi,mf,pi,pf) \ + ((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | ((mi) << MUX_I) | \ + ((mf) << MUX_F) | ((pi) << PAD_I) | ((pf) << PAD_F) + +#define _MXC_BUILD_GPIO_PIN(gp,gi,mi,mf,pi,pf) \ + _MXC_BUILD_PIN(gp,gi,mi,mf,pi,pf) +#define _MXC_BUILD_NON_GPIO_PIN(mi,mf,pi,pf) \ + _MXC_BUILD_PIN(7,0,mi,mf,pi,pf) + +/*! + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ +enum iomux_pins { + MX31_PIN_CSPI3_MISO = _MXC_BUILD_NON_GPIO_PIN(0, 3, 1, 2), + MX31_PIN_CSPI3_SCLK = _MXC_BUILD_NON_GPIO_PIN(0, 2, 1, 1), + MX31_PIN_CSPI3_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(0, 1, 1, 0), + MX31_PIN_TTM_PAD = _MXC_BUILD_NON_GPIO_PIN(0, 0, 0, 2), + MX31_PIN_ATA_RESET_B = _MXC_BUILD_GPIO_PIN(2, 31, 1, 3, 3, 0), + MX31_PIN_CE_CONTROL = _MXC_BUILD_NON_GPIO_PIN(1, 2, 2, 2), + MX31_PIN_CLKSS = _MXC_BUILD_NON_GPIO_PIN(1, 1, 2, 1), + MX31_PIN_CSPI3_MOSI = _MXC_BUILD_NON_GPIO_PIN(1, 0, 2, 0), + MX31_PIN_ATA_CS1 = _MXC_BUILD_GPIO_PIN(2, 27, 2, 3, 4, 1), + MX31_PIN_ATA_DIOR = _MXC_BUILD_GPIO_PIN(2, 28, 2, 2, 4, 0), + MX31_PIN_ATA_DIOW = _MXC_BUILD_GPIO_PIN(2, 29, 2, 1, 3, 2), + MX31_PIN_ATA_DMACK = _MXC_BUILD_GPIO_PIN(2, 30, 2, 0, 3, 1), + MX31_PIN_SD1_DATA1 = _MXC_BUILD_GPIO_PIN(1, 29, 3, 3, 5, 2), + MX31_PIN_SD1_DATA2 = _MXC_BUILD_GPIO_PIN(1, 30, 3, 2, 5, 1), + MX31_PIN_SD1_DATA3 = _MXC_BUILD_GPIO_PIN(1, 31, 3, 1, 5, 0), + MX31_PIN_ATA_CS0 = _MXC_BUILD_GPIO_PIN(2, 26, 3, 0, 4, 2), + MX31_PIN_D3_SPL = _MXC_BUILD_NON_GPIO_PIN(4, 3, 7, 0), + MX31_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN(1, 26, 4, 2, 6, 2), + MX31_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN(1, 27, 4, 1, 6, 1), + MX31_PIN_SD1_DATA0 = _MXC_BUILD_GPIO_PIN(1, 28, 4, 0, 6, 0), + MX31_PIN_VSYNC3 = _MXC_BUILD_NON_GPIO_PIN(5, 3, 8, 1), + MX31_PIN_CONTRAST = _MXC_BUILD_NON_GPIO_PIN(5, 2, 8, 0), + MX31_PIN_D3_REV = _MXC_BUILD_NON_GPIO_PIN(5, 1, 7, 2), + MX31_PIN_D3_CLS = _MXC_BUILD_NON_GPIO_PIN(5, 0, 7, 1), + MX31_PIN_SER_RS = _MXC_BUILD_GPIO_PIN(2, 25, 6, 3, 9, 2), + MX31_PIN_PAR_RS = _MXC_BUILD_NON_GPIO_PIN(6, 2, 9, 1), + MX31_PIN_WRITE = _MXC_BUILD_NON_GPIO_PIN(6, 1, 9, 0), + MX31_PIN_READ = _MXC_BUILD_NON_GPIO_PIN(6, 0, 8, 2), + MX31_PIN_SD_D_IO = _MXC_BUILD_GPIO_PIN(2, 21, 7, 3, 11, 0), + MX31_PIN_SD_D_CLK = _MXC_BUILD_GPIO_PIN(2, 22, 7, 2, 10, 2), + MX31_PIN_LCS0 = _MXC_BUILD_GPIO_PIN(2, 23, 7, 1, 10, 1), + MX31_PIN_LCS1 = _MXC_BUILD_GPIO_PIN(2, 24, 7, 0, 10, 0), + MX31_PIN_HSYNC = _MXC_BUILD_NON_GPIO_PIN(8, 3, 12, 1), + MX31_PIN_FPSHIFT = _MXC_BUILD_NON_GPIO_PIN(8, 2, 12, 0), + MX31_PIN_DRDY0 = _MXC_BUILD_NON_GPIO_PIN(8, 1, 11, 2), + MX31_PIN_SD_D_I = _MXC_BUILD_GPIO_PIN(2, 20, 8, 0, 11, 1), + MX31_PIN_LD15 = _MXC_BUILD_NON_GPIO_PIN(9, 3, 13, 2), + MX31_PIN_LD16 = _MXC_BUILD_NON_GPIO_PIN(9, 2, 13, 1), + MX31_PIN_LD17 = _MXC_BUILD_NON_GPIO_PIN(9, 1, 13, 0), + MX31_PIN_VSYNC0 = _MXC_BUILD_NON_GPIO_PIN(9, 0, 12, 2), + MX31_PIN_LD11 = _MXC_BUILD_NON_GPIO_PIN(10, 3, 15, 0), + MX31_PIN_LD12 = _MXC_BUILD_NON_GPIO_PIN(10, 2, 14, 2), + MX31_PIN_LD13 = _MXC_BUILD_NON_GPIO_PIN(10, 1, 14, 1), + MX31_PIN_LD14 = _MXC_BUILD_NON_GPIO_PIN(10, 0, 14, 0), + MX31_PIN_LD7 = _MXC_BUILD_NON_GPIO_PIN(11, 3, 16, 1), + MX31_PIN_LD8 = _MXC_BUILD_NON_GPIO_PIN(11, 2, 16, 0), + MX31_PIN_LD9 = _MXC_BUILD_NON_GPIO_PIN(11, 1, 15, 2), + MX31_PIN_LD10 = _MXC_BUILD_NON_GPIO_PIN(11, 0, 15, 1), + MX31_PIN_LD3 = _MXC_BUILD_NON_GPIO_PIN(12, 3, 17, 2), + MX31_PIN_LD4 = _MXC_BUILD_NON_GPIO_PIN(12, 2, 17, 1), + MX31_PIN_LD5 = _MXC_BUILD_NON_GPIO_PIN(12, 1, 17, 0), + MX31_PIN_LD6 = _MXC_BUILD_NON_GPIO_PIN(12, 0, 16, 2), + MX31_PIN_USBH2_DATA1 = _MXC_BUILD_NON_GPIO_PIN(13, 3, 19, 0), + MX31_PIN_LD0 = _MXC_BUILD_NON_GPIO_PIN(13, 2, 18, 2), + MX31_PIN_LD1 = _MXC_BUILD_NON_GPIO_PIN(13, 1, 18, 1), + MX31_PIN_LD2 = _MXC_BUILD_NON_GPIO_PIN(13, 0, 18, 0), + MX31_PIN_USBH2_DIR = _MXC_BUILD_NON_GPIO_PIN(14, 3, 20, 1), + MX31_PIN_USBH2_STP = _MXC_BUILD_NON_GPIO_PIN(14, 2, 20, 0), + MX31_PIN_USBH2_NXT = _MXC_BUILD_NON_GPIO_PIN(14, 1, 19, 2), + MX31_PIN_USBH2_DATA0 = _MXC_BUILD_NON_GPIO_PIN(14, 0, 19, 1), + MX31_PIN_USBOTG_DATA5 = _MXC_BUILD_NON_GPIO_PIN(15, 3, 21, 2), + MX31_PIN_USBOTG_DATA6 = _MXC_BUILD_NON_GPIO_PIN(15, 2, 21, 1), + MX31_PIN_USBOTG_DATA7 = _MXC_BUILD_NON_GPIO_PIN(15, 1, 21, 0), + MX31_PIN_USBH2_CLK = _MXC_BUILD_NON_GPIO_PIN(15, 0, 20, 2), + MX31_PIN_USBOTG_DATA1 = _MXC_BUILD_NON_GPIO_PIN(16, 3, 23, 0), + MX31_PIN_USBOTG_DATA2 = _MXC_BUILD_NON_GPIO_PIN(16, 2, 22, 2), + MX31_PIN_USBOTG_DATA3 = _MXC_BUILD_NON_GPIO_PIN(16, 1, 22, 1), + MX31_PIN_USBOTG_DATA4 = _MXC_BUILD_NON_GPIO_PIN(16, 0, 22, 0), + MX31_PIN_USBOTG_DIR = _MXC_BUILD_NON_GPIO_PIN(17, 3, 24, 1), + MX31_PIN_USBOTG_STP = _MXC_BUILD_NON_GPIO_PIN(17, 2, 24, 0), + MX31_PIN_USBOTG_NXT = _MXC_BUILD_NON_GPIO_PIN(17, 1, 23, 2), + MX31_PIN_USBOTG_DATA0 = _MXC_BUILD_NON_GPIO_PIN(17, 0, 23, 1), + MX31_PIN_USB_PWR = _MXC_BUILD_GPIO_PIN(0, 29, 18, 3, 25, 2), + MX31_PIN_USB_OC = _MXC_BUILD_GPIO_PIN(0, 30, 18, 2, 25, 1), + MX31_PIN_USB_BYP = _MXC_BUILD_GPIO_PIN(0, 31, 18, 1, 25, 0), + MX31_PIN_USBOTG_CLK = _MXC_BUILD_NON_GPIO_PIN(18, 0, 24, 2), + MX31_PIN_TDO = _MXC_BUILD_NON_GPIO_PIN(19, 3, 27, 0), + MX31_PIN_TRSTB = _MXC_BUILD_NON_GPIO_PIN(19, 2, 26, 2), + MX31_PIN_DE_B = _MXC_BUILD_NON_GPIO_PIN(19, 1, 26, 1), + MX31_PIN_SJC_MOD = _MXC_BUILD_NON_GPIO_PIN(19, 0, 26, 0), + MX31_PIN_RTCK = _MXC_BUILD_NON_GPIO_PIN(20, 3, 28, 1), + MX31_PIN_TCK = _MXC_BUILD_NON_GPIO_PIN(20, 2, 28, 0), + MX31_PIN_TMS = _MXC_BUILD_NON_GPIO_PIN(20, 1, 27, 2), + MX31_PIN_TDI = _MXC_BUILD_NON_GPIO_PIN(20, 0, 27, 1), + MX31_PIN_KEY_COL4 = _MXC_BUILD_GPIO_PIN(1, 22, 21, 3, 29, 2), + MX31_PIN_KEY_COL5 = _MXC_BUILD_GPIO_PIN(1, 23, 21, 2, 29, 1), + MX31_PIN_KEY_COL6 = _MXC_BUILD_GPIO_PIN(1, 24, 21, 1, 29, 0), + MX31_PIN_KEY_COL7 = _MXC_BUILD_GPIO_PIN(1, 25, 21, 0, 28, 2), + MX31_PIN_KEY_COL0 = _MXC_BUILD_NON_GPIO_PIN(22, 3, 31, 0), + MX31_PIN_KEY_COL1 = _MXC_BUILD_NON_GPIO_PIN(22, 2, 30, 2), + MX31_PIN_KEY_COL2 = _MXC_BUILD_NON_GPIO_PIN(22, 1, 30, 1), + MX31_PIN_KEY_COL3 = _MXC_BUILD_NON_GPIO_PIN(22, 0, 30, 0), + MX31_PIN_KEY_ROW4 = _MXC_BUILD_GPIO_PIN(1, 18, 23, 3, 32, 1), + MX31_PIN_KEY_ROW5 = _MXC_BUILD_GPIO_PIN(1, 19, 23, 2, 32, 0), + MX31_PIN_KEY_ROW6 = _MXC_BUILD_GPIO_PIN(1, 20, 23, 1, 31, 2), + MX31_PIN_KEY_ROW7 = _MXC_BUILD_GPIO_PIN(1, 21, 23, 0, 31, 1), + MX31_PIN_KEY_ROW0 = _MXC_BUILD_NON_GPIO_PIN(24, 3, 33, 2), + MX31_PIN_KEY_ROW1 = _MXC_BUILD_NON_GPIO_PIN(24, 2, 33, 1), + MX31_PIN_KEY_ROW2 = _MXC_BUILD_NON_GPIO_PIN(24, 1, 33, 0), + MX31_PIN_KEY_ROW3 = _MXC_BUILD_NON_GPIO_PIN(24, 0, 32, 2), + MX31_PIN_TXD2 = _MXC_BUILD_GPIO_PIN(0, 28, 25, 3, 35, 0), + MX31_PIN_RTS2 = _MXC_BUILD_NON_GPIO_PIN(25, 2, 34, 2), + MX31_PIN_CTS2 = _MXC_BUILD_NON_GPIO_PIN(25, 1, 34, 1), + MX31_PIN_BATT_LINE = _MXC_BUILD_GPIO_PIN(1, 17, 25, 0, 34, 0), + MX31_PIN_RI_DTE1 = _MXC_BUILD_GPIO_PIN(1, 14, 26, 3, 36, 1), + MX31_PIN_DCD_DTE1 = _MXC_BUILD_GPIO_PIN(1, 15, 26, 2, 36, 0), + MX31_PIN_DTR_DCE2 = _MXC_BUILD_GPIO_PIN(1, 16, 26, 1, 35, 2), + MX31_PIN_RXD2 = _MXC_BUILD_GPIO_PIN(0, 27, 26, 0, 35, 1), + MX31_PIN_RI_DCE1 = _MXC_BUILD_GPIO_PIN(1, 10, 27, 3, 37, 2), + MX31_PIN_DCD_DCE1 = _MXC_BUILD_GPIO_PIN(1, 11, 27, 2, 37, 1), + MX31_PIN_DTR_DTE1 = _MXC_BUILD_GPIO_PIN(1, 12, 27, 1, 37, 0), + MX31_PIN_DSR_DTE1 = _MXC_BUILD_GPIO_PIN(1, 13, 27, 0, 36, 2), + MX31_PIN_RTS1 = _MXC_BUILD_GPIO_PIN(1, 6, 28, 3, 39, 0), + MX31_PIN_CTS1 = _MXC_BUILD_GPIO_PIN(1, 7, 28, 2, 38, 2), + MX31_PIN_DTR_DCE1 = _MXC_BUILD_GPIO_PIN(1, 8, 28, 1, 38, 1), + MX31_PIN_DSR_DCE1 = _MXC_BUILD_GPIO_PIN(1, 9, 28, 0, 38, 0), + MX31_PIN_CSPI2_SCLK = _MXC_BUILD_NON_GPIO_PIN(29, 3, 40, 1), + MX31_PIN_CSPI2_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(29, 2, 40, 0), + MX31_PIN_RXD1 = _MXC_BUILD_GPIO_PIN(1, 4, 29, 1, 39, 2), + MX31_PIN_TXD1 = _MXC_BUILD_GPIO_PIN(1, 5, 29, 0, 39, 1), + MX31_PIN_CSPI2_MISO = _MXC_BUILD_NON_GPIO_PIN(30, 3, 41, 2), + MX31_PIN_CSPI2_SS0 = _MXC_BUILD_NON_GPIO_PIN(30, 2, 41, 1), + MX31_PIN_CSPI2_SS1 = _MXC_BUILD_NON_GPIO_PIN(30, 1, 41, 0), + MX31_PIN_CSPI2_SS2 = _MXC_BUILD_NON_GPIO_PIN(30, 0, 40, 2), + MX31_PIN_CSPI1_SS2 = _MXC_BUILD_NON_GPIO_PIN(31, 3, 43, 0), + MX31_PIN_CSPI1_SCLK = _MXC_BUILD_NON_GPIO_PIN(31, 2, 42, 2), + MX31_PIN_CSPI1_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(31, 1, 42, 1), + MX31_PIN_CSPI2_MOSI = _MXC_BUILD_NON_GPIO_PIN(31, 0, 42, 0), + MX31_PIN_CSPI1_MOSI = _MXC_BUILD_NON_GPIO_PIN(32, 3, 44, 1), + MX31_PIN_CSPI1_MISO = _MXC_BUILD_NON_GPIO_PIN(32, 2, 44, 0), + MX31_PIN_CSPI1_SS0 = _MXC_BUILD_NON_GPIO_PIN(32, 1, 43, 2), + MX31_PIN_CSPI1_SS1 = _MXC_BUILD_NON_GPIO_PIN(32, 0, 43, 1), + MX31_PIN_STXD6 = _MXC_BUILD_GPIO_PIN(0, 23, 33, 3, 45, 2), + MX31_PIN_SRXD6 = _MXC_BUILD_GPIO_PIN(0, 24, 33, 2, 45, 1), + MX31_PIN_SCK6 = _MXC_BUILD_GPIO_PIN(0, 25, 33, 1, 45, 0), + MX31_PIN_SFS6 = _MXC_BUILD_GPIO_PIN(0, 26, 33, 0, 44, 2), + MX31_PIN_STXD5 = _MXC_BUILD_GPIO_PIN(0, 21, 34, 3, 47, 0), + MX31_PIN_SRXD5 = _MXC_BUILD_GPIO_PIN(0, 22, 34, 2, 46, 2), + MX31_PIN_SCK5 = _MXC_BUILD_NON_GPIO_PIN(34, 1, 46, 1), + MX31_PIN_SFS5 = _MXC_BUILD_NON_GPIO_PIN(34, 0, 46, 0), + MX31_PIN_STXD4 = _MXC_BUILD_GPIO_PIN(0, 19, 35, 3, 48, 1), + MX31_PIN_SRXD4 = _MXC_BUILD_GPIO_PIN(0, 20, 35, 2, 48, 0), + MX31_PIN_SCK4 = _MXC_BUILD_NON_GPIO_PIN(35, 1, 47, 2), + MX31_PIN_SFS4 = _MXC_BUILD_NON_GPIO_PIN(35, 0, 47, 1), + MX31_PIN_STXD3 = _MXC_BUILD_GPIO_PIN(0, 17, 36, 3, 49, 2), + MX31_PIN_SRXD3 = _MXC_BUILD_GPIO_PIN(0, 18, 36, 2, 49, 1), + MX31_PIN_SCK3 = _MXC_BUILD_NON_GPIO_PIN(36, 1, 49, 0), + MX31_PIN_SFS3 = _MXC_BUILD_NON_GPIO_PIN(36, 0, 48, 2), + MX31_PIN_CSI_HSYNC = _MXC_BUILD_GPIO_PIN(2, 18, 37, 3, 51, 0), + MX31_PIN_CSI_PIXCLK = _MXC_BUILD_GPIO_PIN(2, 19, 37, 2, 50, 2), + MX31_PIN_I2C_CLK = _MXC_BUILD_NON_GPIO_PIN(37, 1, 50, 1), + MX31_PIN_I2C_DAT = _MXC_BUILD_NON_GPIO_PIN(37, 0, 50, 0), + MX31_PIN_CSI_D14 = _MXC_BUILD_GPIO_PIN(2, 14, 38, 3, 52, 1), + MX31_PIN_CSI_D15 = _MXC_BUILD_GPIO_PIN(2, 15, 38, 2, 52, 0), + MX31_PIN_CSI_MCLK = _MXC_BUILD_GPIO_PIN(2, 16, 38, 1, 51, 2), + MX31_PIN_CSI_VSYNC = _MXC_BUILD_GPIO_PIN(2, 17, 38, 0, 51, 1), + MX31_PIN_CSI_D10 = _MXC_BUILD_GPIO_PIN(2, 10, 39, 3, 53, 2), + MX31_PIN_CSI_D11 = _MXC_BUILD_GPIO_PIN(2, 11, 39, 2, 53, 1), + MX31_PIN_CSI_D12 = _MXC_BUILD_GPIO_PIN(2, 12, 39, 1, 53, 0), + MX31_PIN_CSI_D13 = _MXC_BUILD_GPIO_PIN(2, 13, 39, 0, 52, 2), + MX31_PIN_CSI_D6 = _MXC_BUILD_GPIO_PIN(2, 6, 40, 3, 55, 0), + MX31_PIN_CSI_D7 = _MXC_BUILD_GPIO_PIN(2, 7, 40, 2, 54, 2), + MX31_PIN_CSI_D8 = _MXC_BUILD_GPIO_PIN(2, 8, 40, 1, 54, 1), + MX31_PIN_CSI_D9 = _MXC_BUILD_GPIO_PIN(2, 9, 40, 0, 54, 0), + MX31_PIN_M_REQUEST = _MXC_BUILD_NON_GPIO_PIN(41, 3, 56, 1), + MX31_PIN_M_GRANT = _MXC_BUILD_NON_GPIO_PIN(41, 2, 56, 0), + MX31_PIN_CSI_D4 = _MXC_BUILD_GPIO_PIN(2, 4, 41, 1, 55, 2), + MX31_PIN_CSI_D5 = _MXC_BUILD_GPIO_PIN(2, 5, 41, 0, 55, 1), + MX31_PIN_PC_RST = _MXC_BUILD_NON_GPIO_PIN(42, 3, 57, 2), + MX31_PIN_IOIS16 = _MXC_BUILD_NON_GPIO_PIN(42, 2, 57, 1), + MX31_PIN_PC_RW_B = _MXC_BUILD_NON_GPIO_PIN(42, 1, 57, 0), + MX31_PIN_PC_POE = _MXC_BUILD_NON_GPIO_PIN(42, 0, 56, 2), + MX31_PIN_PC_VS1 = _MXC_BUILD_NON_GPIO_PIN(43, 3, 59, 0), + MX31_PIN_PC_VS2 = _MXC_BUILD_NON_GPIO_PIN(43, 2, 58, 2), + MX31_PIN_PC_BVD1 = _MXC_BUILD_NON_GPIO_PIN(43, 1, 58, 1), + MX31_PIN_PC_BVD2 = _MXC_BUILD_NON_GPIO_PIN(43, 0, 58, 0), + MX31_PIN_PC_CD2_B = _MXC_BUILD_NON_GPIO_PIN(44, 3, 60, 1), + MX31_PIN_PC_WAIT_B = _MXC_BUILD_NON_GPIO_PIN(44, 2, 60, 0), + MX31_PIN_PC_READY = _MXC_BUILD_NON_GPIO_PIN(44, 1, 59, 2), + MX31_PIN_PC_PWRON = _MXC_BUILD_NON_GPIO_PIN(44, 0, 59, 1), + MX31_PIN_D2 = _MXC_BUILD_NON_GPIO_PIN(45, 3, 61, 2), + MX31_PIN_D1 = _MXC_BUILD_NON_GPIO_PIN(45, 2, 61, 1), + MX31_PIN_D0 = _MXC_BUILD_NON_GPIO_PIN(45, 1, 61, 0), + MX31_PIN_PC_CD1_B = _MXC_BUILD_NON_GPIO_PIN(45, 0, 60, 2), + MX31_PIN_D6 = _MXC_BUILD_NON_GPIO_PIN(46, 3, 63, 0), + MX31_PIN_D5 = _MXC_BUILD_NON_GPIO_PIN(46, 2, 62, 2), + MX31_PIN_D4 = _MXC_BUILD_NON_GPIO_PIN(46, 1, 62, 1), + MX31_PIN_D3 = _MXC_BUILD_NON_GPIO_PIN(46, 0, 62, 0), + MX31_PIN_D10 = _MXC_BUILD_NON_GPIO_PIN(47, 3, 64, 1), + MX31_PIN_D9 = _MXC_BUILD_NON_GPIO_PIN(47, 2, 64, 0), + MX31_PIN_D8 = _MXC_BUILD_NON_GPIO_PIN(47, 1, 63, 2), + MX31_PIN_D7 = _MXC_BUILD_NON_GPIO_PIN(47, 0, 63, 1), + MX31_PIN_D14 = _MXC_BUILD_NON_GPIO_PIN(48, 3, 65, 2), + MX31_PIN_D13 = _MXC_BUILD_NON_GPIO_PIN(48, 2, 65, 1), + MX31_PIN_D12 = _MXC_BUILD_NON_GPIO_PIN(48, 1, 65, 0), + MX31_PIN_D11 = _MXC_BUILD_NON_GPIO_PIN(48, 0, 64, 2), + MX31_PIN_NFWP_B = _MXC_BUILD_GPIO_PIN(0, 14, 49, 3, 67, 0), + MX31_PIN_NFCE_B = _MXC_BUILD_GPIO_PIN(0, 15, 49, 2, 66, 2), + MX31_PIN_NFRB = _MXC_BUILD_GPIO_PIN(0, 16, 49, 1, 66, 1), + MX31_PIN_D15 = _MXC_BUILD_NON_GPIO_PIN(49, 0, 66, 0), + MX31_PIN_NFWE_B = _MXC_BUILD_GPIO_PIN(0, 10, 50, 3, 68, 1), + MX31_PIN_NFRE_B = _MXC_BUILD_GPIO_PIN(0, 11, 50, 2, 68, 0), + MX31_PIN_NFALE = _MXC_BUILD_GPIO_PIN(0, 12, 50, 1, 67, 2), + MX31_PIN_NFCLE = _MXC_BUILD_GPIO_PIN(0, 13, 50, 0, 67, 1), + MX31_PIN_SDQS0 = _MXC_BUILD_NON_GPIO_PIN(51, 3, 69, 2), + MX31_PIN_SDQS1 = _MXC_BUILD_NON_GPIO_PIN(51, 2, 69, 1), + MX31_PIN_SDQS2 = _MXC_BUILD_NON_GPIO_PIN(51, 1, 69, 0), + MX31_PIN_SDQS3 = _MXC_BUILD_NON_GPIO_PIN(51, 0, 68, 2), + MX31_PIN_SDCKE0 = _MXC_BUILD_NON_GPIO_PIN(52, 3, 71, 0), + MX31_PIN_SDCKE1 = _MXC_BUILD_NON_GPIO_PIN(52, 2, 70, 2), + MX31_PIN_SDCLK = _MXC_BUILD_NON_GPIO_PIN(52, 1, 70, 1), + MX31_PIN_SDCLK_B = _MXC_BUILD_NON_GPIO_PIN(52, 0, 70, 0), + MX31_PIN_RW = _MXC_BUILD_NON_GPIO_PIN(53, 3, 72, 1), + MX31_PIN_RAS = _MXC_BUILD_NON_GPIO_PIN(53, 2, 72, 0), + MX31_PIN_CAS = _MXC_BUILD_NON_GPIO_PIN(53, 1, 71, 2), + MX31_PIN_SDWE = _MXC_BUILD_NON_GPIO_PIN(53, 0, 71, 1), + MX31_PIN_CS5 = _MXC_BUILD_NON_GPIO_PIN(54, 3, 73, 2), + MX31_PIN_ECB = _MXC_BUILD_NON_GPIO_PIN(54, 2, 73, 1), + MX31_PIN_LBA = _MXC_BUILD_NON_GPIO_PIN(54, 1, 73, 0), + MX31_PIN_BCLK = _MXC_BUILD_NON_GPIO_PIN(54, 0, 72, 2), + MX31_PIN_CS1 = _MXC_BUILD_NON_GPIO_PIN(55, 3, 75, 0), + MX31_PIN_CS2 = _MXC_BUILD_NON_GPIO_PIN(55, 2, 74, 2), + MX31_PIN_CS3 = _MXC_BUILD_NON_GPIO_PIN(55, 1, 74, 1), + MX31_PIN_CS4 = _MXC_BUILD_NON_GPIO_PIN(55, 0, 74, 0), + MX31_PIN_EB0 = _MXC_BUILD_NON_GPIO_PIN(56, 3, 76, 1), + MX31_PIN_EB1 = _MXC_BUILD_NON_GPIO_PIN(56, 2, 76, 0), + MX31_PIN_OE = _MXC_BUILD_NON_GPIO_PIN(56, 1, 75, 2), + MX31_PIN_CS0 = _MXC_BUILD_NON_GPIO_PIN(56, 0, 75, 1), + MX31_PIN_DQM0 = _MXC_BUILD_NON_GPIO_PIN(57, 3, 77, 2), + MX31_PIN_DQM1 = _MXC_BUILD_NON_GPIO_PIN(57, 2, 77, 1), + MX31_PIN_DQM2 = _MXC_BUILD_NON_GPIO_PIN(57, 1, 77, 0), + MX31_PIN_DQM3 = _MXC_BUILD_NON_GPIO_PIN(57, 0, 76, 2), + MX31_PIN_SD28 = _MXC_BUILD_NON_GPIO_PIN(58, 3, 79, 0), + MX31_PIN_SD29 = _MXC_BUILD_NON_GPIO_PIN(58, 2, 78, 2), + MX31_PIN_SD30 = _MXC_BUILD_NON_GPIO_PIN(58, 1, 78, 1), + MX31_PIN_SD31 = _MXC_BUILD_NON_GPIO_PIN(58, 0, 78, 0), + MX31_PIN_SD24 = _MXC_BUILD_NON_GPIO_PIN(59, 3, 80, 1), + MX31_PIN_SD25 = _MXC_BUILD_NON_GPIO_PIN(59, 2, 80, 0), + MX31_PIN_SD26 = _MXC_BUILD_NON_GPIO_PIN(59, 1, 79, 2), + MX31_PIN_SD27 = _MXC_BUILD_NON_GPIO_PIN(59, 0, 79, 1), + MX31_PIN_SD20 = _MXC_BUILD_NON_GPIO_PIN(60, 3, 81, 2), + MX31_PIN_SD21 = _MXC_BUILD_NON_GPIO_PIN(60, 2, 81, 1), + MX31_PIN_SD22 = _MXC_BUILD_NON_GPIO_PIN(60, 1, 81, 0), + MX31_PIN_SD23 = _MXC_BUILD_NON_GPIO_PIN(60, 0, 80, 2), + MX31_PIN_SD16 = _MXC_BUILD_NON_GPIO_PIN(61, 3, 83, 0), + MX31_PIN_SD17 = _MXC_BUILD_NON_GPIO_PIN(61, 2, 82, 2), + MX31_PIN_SD18 = _MXC_BUILD_NON_GPIO_PIN(61, 1, 82, 1), + MX31_PIN_SD19 = _MXC_BUILD_NON_GPIO_PIN(61, 0, 82, 0), + MX31_PIN_SD12 = _MXC_BUILD_NON_GPIO_PIN(62, 3, 84, 1), + MX31_PIN_SD13 = _MXC_BUILD_NON_GPIO_PIN(62, 2, 84, 0), + MX31_PIN_SD14 = _MXC_BUILD_NON_GPIO_PIN(62, 1, 83, 2), + MX31_PIN_SD15 = _MXC_BUILD_NON_GPIO_PIN(62, 0, 83, 1), + MX31_PIN_SD8 = _MXC_BUILD_NON_GPIO_PIN(63, 3, 85, 2), + MX31_PIN_SD9 = _MXC_BUILD_NON_GPIO_PIN(63, 2, 85, 1), + MX31_PIN_SD10 = _MXC_BUILD_NON_GPIO_PIN(63, 1, 85, 0), + MX31_PIN_SD11 = _MXC_BUILD_NON_GPIO_PIN(63, 0, 84, 2), + MX31_PIN_SD4 = _MXC_BUILD_NON_GPIO_PIN(64, 3, 87, 0), + MX31_PIN_SD5 = _MXC_BUILD_NON_GPIO_PIN(64, 2, 86, 2), + MX31_PIN_SD6 = _MXC_BUILD_NON_GPIO_PIN(64, 1, 86, 1), + MX31_PIN_SD7 = _MXC_BUILD_NON_GPIO_PIN(64, 0, 86, 0), + MX31_PIN_SD0 = _MXC_BUILD_NON_GPIO_PIN(65, 3, 88, 1), + MX31_PIN_SD1 = _MXC_BUILD_NON_GPIO_PIN(65, 2, 88, 0), + MX31_PIN_SD2 = _MXC_BUILD_NON_GPIO_PIN(65, 1, 87, 2), + MX31_PIN_SD3 = _MXC_BUILD_NON_GPIO_PIN(65, 0, 87, 1), + MX31_PIN_A24 = _MXC_BUILD_NON_GPIO_PIN(66, 3, 89, 2), + MX31_PIN_A25 = _MXC_BUILD_NON_GPIO_PIN(66, 2, 89, 1), + MX31_PIN_SDBA1 = _MXC_BUILD_NON_GPIO_PIN(66, 1, 89, 0), + MX31_PIN_SDBA0 = _MXC_BUILD_NON_GPIO_PIN(66, 0, 88, 2), + MX31_PIN_A20 = _MXC_BUILD_NON_GPIO_PIN(67, 3, 91, 0), + MX31_PIN_A21 = _MXC_BUILD_NON_GPIO_PIN(67, 2, 90, 2), + MX31_PIN_A22 = _MXC_BUILD_NON_GPIO_PIN(67, 1, 90, 1), + MX31_PIN_A23 = _MXC_BUILD_NON_GPIO_PIN(67, 0, 90, 0), + MX31_PIN_A16 = _MXC_BUILD_NON_GPIO_PIN(68, 3, 92, 1), + MX31_PIN_A17 = _MXC_BUILD_NON_GPIO_PIN(68, 2, 92, 0), + MX31_PIN_A18 = _MXC_BUILD_NON_GPIO_PIN(68, 1, 91, 2), + MX31_PIN_A19 = _MXC_BUILD_NON_GPIO_PIN(68, 0, 91, 1), + MX31_PIN_A12 = _MXC_BUILD_NON_GPIO_PIN(69, 3, 93, 2), + MX31_PIN_A13 = _MXC_BUILD_NON_GPIO_PIN(69, 2, 93, 1), + MX31_PIN_A14 = _MXC_BUILD_NON_GPIO_PIN(69, 1, 93, 0), + MX31_PIN_A15 = _MXC_BUILD_NON_GPIO_PIN(69, 0, 92, 2), + MX31_PIN_A9 = _MXC_BUILD_NON_GPIO_PIN(70, 3, 95, 0), + MX31_PIN_A10 = _MXC_BUILD_NON_GPIO_PIN(70, 2, 94, 2), + MX31_PIN_MA10 = _MXC_BUILD_NON_GPIO_PIN(70, 1, 94, 1), + MX31_PIN_A11 = _MXC_BUILD_NON_GPIO_PIN(70, 0, 94, 0), + MX31_PIN_A5 = _MXC_BUILD_NON_GPIO_PIN(71, 3, 96, 1), + MX31_PIN_A6 = _MXC_BUILD_NON_GPIO_PIN(71, 2, 96, 0), + MX31_PIN_A7 = _MXC_BUILD_NON_GPIO_PIN(71, 1, 95, 2), + MX31_PIN_A8 = _MXC_BUILD_NON_GPIO_PIN(71, 0, 95, 1), + MX31_PIN_A1 = _MXC_BUILD_NON_GPIO_PIN(72, 3, 97, 2), + MX31_PIN_A2 = _MXC_BUILD_NON_GPIO_PIN(72, 2, 97, 1), + MX31_PIN_A3 = _MXC_BUILD_NON_GPIO_PIN(72, 1, 97, 0), + MX31_PIN_A4 = _MXC_BUILD_NON_GPIO_PIN(72, 0, 96, 2), + MX31_PIN_DVFS1 = _MXC_BUILD_NON_GPIO_PIN(73, 3, 99, 0), + MX31_PIN_VPG0 = _MXC_BUILD_NON_GPIO_PIN(73, 2, 98, 2), + MX31_PIN_VPG1 = _MXC_BUILD_NON_GPIO_PIN(73, 1, 98, 1), + MX31_PIN_A0 = _MXC_BUILD_NON_GPIO_PIN(73, 0, 98, 0), + MX31_PIN_CKIL = _MXC_BUILD_NON_GPIO_PIN(74, 3, 100, 1), + MX31_PIN_POWER_FAIL = _MXC_BUILD_NON_GPIO_PIN(74, 2, 100, 0), + MX31_PIN_VSTBY = _MXC_BUILD_NON_GPIO_PIN(74, 1, 99, 2), + MX31_PIN_DVFS0 = _MXC_BUILD_NON_GPIO_PIN(74, 0, 99, 1), + MX31_PIN_BOOT_MODE1 = _MXC_BUILD_NON_GPIO_PIN(75, 3, 101, 2), + MX31_PIN_BOOT_MODE2 = _MXC_BUILD_NON_GPIO_PIN(75, 2, 101, 1), + MX31_PIN_BOOT_MODE3 = _MXC_BUILD_NON_GPIO_PIN(75, 1, 101, 0), + MX31_PIN_BOOT_MODE4 = _MXC_BUILD_NON_GPIO_PIN(75, 0, 100, 2), + MX31_PIN_RESET_IN_B = _MXC_BUILD_NON_GPIO_PIN(76, 3, 103, 0), + MX31_PIN_POR_B = _MXC_BUILD_NON_GPIO_PIN(76, 2, 102, 2), + MX31_PIN_CLKO = _MXC_BUILD_NON_GPIO_PIN(76, 1, 102, 1), + MX31_PIN_BOOT_MODE0 = _MXC_BUILD_NON_GPIO_PIN(76, 0, 102, 0), + MX31_PIN_STX0 = _MXC_BUILD_GPIO_PIN(1, 1, 77, 3, 104, 1), + MX31_PIN_SRX0 = _MXC_BUILD_GPIO_PIN(1, 2, 77, 2, 104, 0), + MX31_PIN_SIMPD0 = _MXC_BUILD_GPIO_PIN(1, 3, 77, 1, 103, 2), + MX31_PIN_CKIH = _MXC_BUILD_NON_GPIO_PIN(77, 0, 103, 1), + MX31_PIN_GPIO3_1 = _MXC_BUILD_GPIO_PIN(2, 1, 78, 3, 105, 2), + MX31_PIN_SCLK0 = _MXC_BUILD_GPIO_PIN(2, 2, 78, 2, 105, 1), + MX31_PIN_SRST0 = _MXC_BUILD_GPIO_PIN(2, 3, 78, 1, 105, 0), + MX31_PIN_SVEN0 = _MXC_BUILD_GPIO_PIN(1, 0, 78, 0, 104, 2), + MX31_PIN_GPIO1_4 = _MXC_BUILD_GPIO_PIN(0, 4, 79, 3, 107, 0), + MX31_PIN_GPIO1_5 = _MXC_BUILD_GPIO_PIN(0, 5, 79, 2, 106, 2), + MX31_PIN_GPIO1_6 = _MXC_BUILD_GPIO_PIN(0, 6, 79, 1, 106, 1), + MX31_PIN_GPIO3_0 = _MXC_BUILD_GPIO_PIN(2, 0, 79, 0, 106, 0), + MX31_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 80, 3, 108, 1), + MX31_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 80, 2, 108, 0), + MX31_PIN_GPIO1_2 = _MXC_BUILD_GPIO_PIN(0, 2, 80, 1, 107, 2), + MX31_PIN_GPIO1_3 = _MXC_BUILD_GPIO_PIN(0, 3, 80, 0, 107, 1), + MX31_PIN_CAPTURE = _MXC_BUILD_GPIO_PIN(0, 7, 81, 3, 109, 2), + MX31_PIN_COMPARE = _MXC_BUILD_GPIO_PIN(0, 8, 81, 2, 109, 1), + MX31_PIN_WATCHDOG_RST = _MXC_BUILD_NON_GPIO_PIN(81, 1, 109, 0), + MX31_PIN_PWMO = _MXC_BUILD_GPIO_PIN(0, 9, 81, 0, 108, 2), +}; + +#endif +#endif diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 30e2767a78ae..c9526bc5e22c 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2000 Deep Blue Solutions Ltd * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,19 +23,30 @@ #include <linux/clk.h> #include <linux/serial_8250.h> #include <linux/gpio.h> +#include <linux/input.h> +#include <linux/nodemask.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <linux/spi/spi.h> #include <linux/i2c.h> #include <linux/irq.h> +#include <linux/ata.h> +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach/flash.h> +#endif #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/mach/keypad.h> #include <asm/mach/time.h> #include <asm/memory.h> #include <asm/mach/map.h> #include <mach/common.h> -#include <mach/board-mx31ads.h> -#include <mach/imx-uart.h> -#include <mach/iomux-mx3.h> #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 #include <linux/mfd/wm8350/audio.h> @@ -43,8 +54,13 @@ #include <linux/mfd/wm8350/pmic.h> #endif -#include "devices.h" +#include <mach/memory.h> +#include <mach/mmc.h> +#include <mach/spba.h> +#include "board-mx31ads.h" +#include "crm_regs.h" +#include "iomux.h" /*! * @file mx31ads.c * @@ -53,6 +69,95 @@ * @ingroup System */ +extern void mx31ads_gpio_init(void) __init; + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_CS89x0) || defined(CONFIG_CS89x0_MODULE) +/*! Null terminated portlist used to probe for the CS8900A device on ISA Bus + * Add 3 to reset the page window before probing (fixes eth probe when deployed + * using nand_boot) + */ +unsigned int netcard_portlist[] = { (u32)CS8900A_BASE_ADDRESS + 3, 0 }; + +EXPORT_SYMBOL(netcard_portlist); +/*! + * The CS8900A has 4 IRQ pins, which is software selectable, CS8900A interrupt + * pin 0 is used for interrupt generation. + */ +unsigned int cs8900_irq_map[] = { CS8900AIRQ, 0, 0, 0 }; + +EXPORT_SYMBOL(cs8900_irq_map); +#endif + +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) + +/* Keypad keycodes for the EVB 8x8 + * keypad. POWER and PTT keys don't generate + * any interrupts via this driver so they are + * not support. Change any keys as u like! + */ +static u16 keymapping[64] = { + KEY_SELECT, KEY_LEFT, KEY_DOWN, KEY_RIGHT, + KEY_UP, KEY_F12, KEY_END, KEY_BACK, + KEY_F1, KEY_SENDFILE, KEY_HOME, KEY_F6, + KEY_VOLUMEUP, KEY_F8, KEY_F9, KEY_F10, + KEY_3, KEY_2, KEY_1, KEY_4, + KEY_VOLUMEDOWN, KEY_7, KEY_5, KEY_6, + KEY_9, KEY_LEFTSHIFT, KEY_8, KEY_0, + KEY_KPASTERISK, KEY_RECORD, KEY_Q, KEY_W, + KEY_A, KEY_S, KEY_D, KEY_E, + KEY_F, KEY_R, KEY_T, KEY_Y, + KEY_TAB, KEY_F7, KEY_CAPSLOCK, KEY_Z, + KEY_X, KEY_C, KEY_V, KEY_G, + KEY_B, KEY_H, KEY_N, KEY_M, + KEY_J, KEY_K, KEY_U, KEY_I, + KEY_SPACE, KEY_F2, KEY_DOT, KEY_ENTER, + KEY_L, KEY_BACKSPACE, KEY_P, KEY_O, +}; + +static struct resource mxc_kpp_resources[] = { + [0] = { + .start = MXC_INT_KPP, + .end = MXC_INT_KPP, + .flags = IORESOURCE_IRQ, + } +}; + +static struct keypad_data evb_8_by_8_keypad = { + .rowmax = 8, + .colmax = 8, + .irq = MXC_INT_KPP, + .learning = 0, + .delay = 2, + .matrix = keymapping, +}; + +/* mxc keypad driver */ +static struct platform_device mxc_keypad_device = { + .name = "mxc_keypad", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_kpp_resources), + .resource = mxc_kpp_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &evb_8_by_8_keypad, + }, +}; + +static void mxc_init_keypad(void) +{ + (void)platform_device_register(&mxc_keypad_device); +} +#else +static inline void mxc_init_keypad(void) +{ +} +#endif + #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) /*! * The serial port definition structure. @@ -96,29 +201,470 @@ static inline int mxc_init_extuart(void) return 0; } #endif +/* MTD NOR flash */ + +#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE) + +static struct mtd_partition mxc_nor_partitions[] = { + { + .name = "Bootloader", + .size = 512 * 1024, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "nor.Kernel", + .size = 2 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0}, + { + .name = "nor.userfs", + .size = 14 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0}, + { + .name = "nor.rootfs", + .size = 12 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE}, + { + .name = "FIS directory", + .size = 12 * 1024, + .offset = 0x01FE0000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .name = "Redboot config", + .size = MTDPART_SIZ_FULL, + .offset = 0x01FFF000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, +}; + +static struct flash_platform_data mxc_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = mxc_nor_partitions, + .nr_parts = ARRAY_SIZE(mxc_nor_partitions), +}; + +static struct resource mxc_flash_resource = { + .start = 0xa0000000, + .end = 0xa0000000 + 0x02000000 - 1, + .flags = IORESOURCE_MEM, + +}; + +static struct platform_device mxc_nor_mtd_device = { + .name = "mxc_nor_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_flash_data, + }, + .num_resources = 1, + .resource = &mxc_flash_resource, +}; + +static void mxc_init_nor_mtd(void) +{ + (void)platform_device_register(&mxc_nor_mtd_device); +} +#else +static void mxc_init_nor_mtd(void) +{ +} +#endif + +/* NAND Flash Partitions */ +#ifdef CONFIG_MTD_PARTITIONS + +static struct mtd_partition nand_flash_partitions[4] = { + { + .name = "nand.bootloader", + .offset = 0, + .size = 1024 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 5 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 22 * 1024 * 1024}, + { + .name = "nand.userfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; + +#endif + +/* MTD NAND flash */ + +#if defined(CONFIG_MTD_NAND_MXC) \ + || defined(CONFIG_MTD_NAND_MXC_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V2) \ + || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) + +static struct flash_platform_data mxc_nand_data = { + #ifdef CONFIG_MTD_PARTITIONS + .parts = nand_flash_partitions, + .nr_parts = ARRAY_SIZE(nand_flash_partitions), + #endif + .width = 1, +}; + +static struct platform_device mxc_nand_mtd_device = { + .name = "mxc_nand_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static struct platform_device mxc_nandv2_mtd_device = { + .name = "mxc_nandv2_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static void mxc_init_nand_mtd(void) +{ + if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) { + mxc_nand_data.width = 2; + } + if (cpu_is_mx31()) { + (void)platform_device_register(&mxc_nand_mtd_device); + } + if (cpu_is_mx32()) { + (void)platform_device_register(&mxc_nandv2_mtd_device); + } +} +#else +static inline void mxc_init_nand_mtd(void) +{ +} +#endif + +/* i.MX MTD NAND Flash Controller */ + +#if defined(CONFIG_MTD_NAND_IMX_NFC) || defined(CONFIG_MTD_NAND_IMX_NFC_MODULE) + +/* Resources for this device. */ + +static struct resource imx_nfc_resources[] = { + { + .flags = IORESOURCE_MEM, + .start = NFC_BASE_ADDR + 0x000, + .end = NFC_BASE_ADDR + 0x840 - 1, + .name = IMX_NFC_BUFFERS_ADDR_RES_NAME, + }, + { + .flags = IORESOURCE_MEM, + .start = NFC_BASE_ADDR + 0xE00, + .end = NFC_BASE_ADDR + 0xE20 - 1, + .name = IMX_NFC_PRIMARY_REGS_ADDR_RES_NAME, + }, + { + .flags = IORESOURCE_IRQ, + .start = MXC_INT_NANDFC, + .end = MXC_INT_NANDFC, + .name = IMX_NFC_INTERRUPT_RES_NAME, + }, +}; + +/** + * imx_nfc_set_page_size() - Tells the hardware the page size. + * + * @data_size_in_bytes: The page size in bytes (e.g., 512, 2048, etc.). This + * size refers specifically to the the data bytes in the + * page, *not* including out-of-band bytes. The return + * value is zero if the operation succeeded. Do not + * interpret a non-zero value as an error code - it only + * indicates failure. The driver will decide what error + * code to return to its caller. + */ +static int imx_nfc_set_page_size(unsigned int data_size_in_bytes) +{ + + unsigned long x = __raw_readl(MXC_CCM_RCSR); + + switch (data_size_in_bytes) { + + case 512: + x &= ~MXC_CCM_RCSR_NFMS; + break; + + case 2048: + x |= MXC_CCM_RCSR_NFMS; + break; + + default: + return !0; + break; + + } + + __raw_writel(x, MXC_CCM_RCSR); + + return 0; + +} + +/* + * Platform-specific information about this device. Some of the details depend + * on the SoC. See imx_init_nfc() below for code that fills in the rest. + */ + +static struct imx_nfc_platform_data imx_nfc_platform_data = { + .force_ce = false, + .target_cycle_in_ns = 50, + .clock_name = "nfc_clk", + .set_page_size = imx_nfc_set_page_size, + .interleave = false, + #ifdef CONFIG_MTD_PARTITIONS + .partitions = nand_flash_partitions, + .partition_count = ARRAY_SIZE(nand_flash_partitions), + #endif +}; + +/* The structure that represents the NFC device. */ + +static struct platform_device imx_nfc_device = { + .name = IMX_NFC_DRIVER_NAME, + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &imx_nfc_platform_data, + }, + .resource = imx_nfc_resources, + .num_resources = ARRAY_SIZE(imx_nfc_resources), +}; + +/** + * imx_init_nfc() - Sets up the NFC for this platform. + * + * This function sets up data structures representing the NFC device on this + * platform and registers the device with the platform management system. + */ + +static void imx_nfc_init(void) +{ + + /* + * A field in the Reset Control and Source Register register tells us + * the bus width. + */ + + if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) + imx_nfc_platform_data.bus_width_in_bits = 16; + else + imx_nfc_platform_data.bus_width_in_bits = 8; + + /* + * Discover the type of SoC we're running on and, based on that, fill in + * some details about the NFC. + */ + + if (cpu_is_mx31()) { + imx_nfc_platform_data.major_version = 1; + imx_nfc_platform_data.minor_version = 0; + } else if (cpu_is_mx32()) { + imx_nfc_platform_data.major_version = 2; + imx_nfc_platform_data.minor_version = 0; + } else { + pr_err("imx_nfc: Can't identify the SoC\n"); + BUG(); + } + + /* Register the NFC device. */ + + (void)platform_device_register(&imx_nfc_device); + +} + +#else + +static inline void imx_nfc_init(void) +{ +} + +#endif /* i.MX MTD NAND Flash Controller */ + +static struct spi_board_info mxc_spi_board_info[] __initdata = { + { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .max_speed_hz = 4000000, + .bus_num = 2, + .chip_select = 0, + }, +}; + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static const char fb_default_mode[] = "Sharp-QVGA"; + +/* mxc lcd driver */ +static struct platform_device mxc_fb_device = { + .name = "mxc_sdc_fb", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &fb_default_mode, + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +static void mxc_init_fb(void) +{ + (void)platform_device_register(&mxc_fb_device); +} +#else +static inline void mxc_init_fb(void) +{ +} +#endif -#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) -static struct imxuart_platform_data uart_pdata = { - .flags = IMXUART_HAVE_RTSCTS, +#if defined(CONFIG_BACKLIGHT_MXC) +static struct platform_device mxcbl_devices[] = { +#if defined(CONFIG_BACKLIGHT_MXC_PMIC) || defined(CONFIG_BACKLIGHT_MXC_PMIC_MODULE) + { + .name = "mxc_pmic_bl", + .id = 0, + .dev = { + .platform_data = (void *)-1, /* DISP # for this backlight */ + }, + }, + { + .name = "mxc_pmic_bl", + .id = 1, + .dev = { + .platform_data = (void *)0, /* DISP # for this backlight */ + }, + }, +#endif +#if defined(CONFIG_BACKLIGHT_MXC_IPU) || defined(CONFIG_BACKLIGHT_MXC_IPU_MODULE) + { + .name = "mxc_ipu_bl", + .id = 0, + .dev = { + .platform_data = (void *)3, /* DISP # for this backlight */ + }, + }, +#endif +}; +static inline void mxc_init_bl(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) { + platform_device_register(&mxcbl_devices[i]); + } +} +#else +static inline void mxc_init_bl(void) +{ +} +#endif + +/*! + * Data structures and data for mt9v111 camera. + */ +static struct mxc_camera_platform_data camera_mt9v111_data = { + .mclk = 27000000, +}; + +/*! + * Data structures and data for ov2640 camera. + */ +static struct mxc_camera_platform_data camera_ov2640_data = { + .core_regulator = NULL, + .io_regulator = NULL, + .analog_regulator = NULL, + .gpo_regulator = NULL, + .mclk = 24000000, }; -static unsigned int uart_pins[] = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1 +/*! + * Info to register i2c devices. + */ +static struct i2c_board_info mxc_i2c_info[] __initdata = { + { + .type = "mt9v111", + .addr = 0x48, + .platform_data = (void *)&camera_mt9v111_data, + }, + { + .type = "ov2640", + .addr = 0x30, + .platform_data = (void *)&camera_ov2640_data, + }, }; -static inline void mxc_init_imx_uart(void) +#if defined(CONFIG_MXC_FIR) || defined(CONFIG_MXC_FIR_MODULE) +/*! + * Resource definition for the FIR + */ +static struct resource mxcir_resources[] = { + [0] = { + .start = UART2_BASE_ADDR, + .end = UART2_BASE_ADDR + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = FIRI_BASE_ADDR, + .end = FIRI_BASE_ADDR + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = MXC_INT_FIRI, + .end = MXC_INT_FIRI, + .flags = IORESOURCE_IRQ, + }, + [4] = { + .start = MXC_INT_UART2, + .end = MXC_INT_UART2, + .flags = IORESOURCE_IRQ, + } +}; + +static struct mxc_ir_platform_data ir_data = { + .uart_ir_mux = 1, + .ir_rx_invert = MXC_IRDA_RX_INV, + .ir_tx_invert = MXC_IRDA_TX_INV, +}; + +/*! Device Definition for MXC FIR */ +static struct platform_device mxcir_device = { + .name = "mxcir", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &ir_data, + }, + .num_resources = ARRAY_SIZE(mxcir_resources), + .resource = mxcir_resources, +}; + +static inline void mxc_init_ir(void) { - mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0"); - mxc_register_device(&mxc_uart_device0, &uart_pdata); + ir_data.uart_clk = clk_get(NULL, "uart_clk.1");; + (void)platform_device_register(&mxcir_device); } -#else /* !SERIAL_IMX */ -static inline void mxc_init_imx_uart(void) +#else +static inline void mxc_init_ir(void) { } -#endif /* !SERIAL_IMX */ +#endif static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc) { @@ -187,7 +733,10 @@ static void __init mx31ads_init_expio(void) /* * Configure INT line as GPIO input */ - mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); + mxc_request_iomux(MX31_PIN_GPIO1_4, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_4), NULL); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_4)); /* disable the interrupt and clear the status */ __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); @@ -462,6 +1011,121 @@ static struct wm8350_platform_data __initdata mx31_wm8350_pdata = { }; #endif +/* MMC device data */ + +#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) +extern unsigned int sdhc_get_card_det_status(struct device *dev); +extern int sdhc_init_card_det(int id); + +static struct mxc_mmc_platform_data mmc1_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30, + .min_clk = 150000, + .max_clk = 25000000, + .card_inserted_state = 1, + .status = sdhc_get_card_det_status, + .power_mmc = "VMMC1", +}; +static struct mxc_mmc_platform_data mmc2_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30, + .min_clk = 150000, + .max_clk = 25000000, + .card_inserted_state = 1, + .status = sdhc_get_card_det_status, + .power_mmc = "VMMC2", +}; +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc1_resources[] = { + [0] = { + .start = MMC_SDHC1_BASE_ADDR, + .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC1, + .end = MXC_INT_MMC_SDHC1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the SDHC2 + */ +static struct resource mxcsdhc2_resources[] = { + [0] = { + .start = MMC_SDHC2_BASE_ADDR, + .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC2, + .end = MXC_INT_MMC_SDHC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC1 */ +static struct platform_device mxcsdhc1_device = { + .name = "mxcmci", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc1_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc1_resources), + .resource = mxcsdhc1_resources, +}; + +/*! Device Definition for MXC SDHC2 */ +static struct platform_device mxcsdhc2_device = { + .name = "mxcmci", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc2_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc2_resources), + .resource = mxcsdhc2_resources, +}; + +static inline void mxc_init_mmc(void) +{ + int cd_irq; + + cd_irq = sdhc_init_card_det(0); + if (cd_irq) { + mxcsdhc1_device.resource[2].start = cd_irq; + mxcsdhc1_device.resource[2].end = cd_irq; + } + + cd_irq = sdhc_init_card_det(1); + if (cd_irq) { + mxcsdhc2_device.resource[2].start = cd_irq; + mxcsdhc2_device.resource[2].end = cd_irq; + } + + spba_take_ownership(SPBA_SDHC1, SPBA_MASTER_A | SPBA_MASTER_C); + (void)platform_device_register(&mxcsdhc1_device); + spba_take_ownership(SPBA_SDHC2, SPBA_MASTER_A | SPBA_MASTER_C); + (void)platform_device_register(&mxcsdhc2_device); +} +#else +static inline void mxc_init_mmc(void) +{ +} +#endif + #if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE) static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 @@ -489,6 +1153,147 @@ static void mxc_init_i2c(void) } #endif +#if (defined(CONFIG_MXC_PMIC_MC13783) || \ + defined(CONFIG_MXC_PMIC_MC13783_MODULE)) \ + && (defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE)) +extern void gpio_activate_audio_ports(void); + +static void __init mxc_init_pmic_audio(void) +{ + struct clk *ckih_clk; + struct clk *cko_clk; + + /* Enable 26 mhz clock on CKO1 for PMIC audio */ + ckih_clk = clk_get(NULL, "ckih"); + cko_clk = clk_get(NULL, "cko1_clk"); + if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) { + printk(KERN_ERR "Unable to set CKO1 output to CKIH\n"); + } else { + clk_set_parent(cko_clk, ckih_clk); + clk_set_rate(cko_clk, clk_get_rate(ckih_clk)); + clk_enable(cko_clk); + } + clk_put(ckih_clk); + clk_put(cko_clk); + + gpio_activate_audio_ports(); +} +#else +static void __inline mxc_init_pmic_audio(void) +{ +} +#endif + +/* IDE device data */ +#if defined(CONFIG_BLK_DEV_IDE_MXC) || defined(CONFIG_BLK_DEV_IDE_MXC_MODULE) + +/*! Platform Data for MXC IDE */ +static struct mxc_ide_platform_data mxc_ide_data = { + .power_drive = NULL, + .power_io = NULL, +}; + +static struct platform_device mxc_ide_device = { + .name = "mxc_ide", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_ide_data, + }, +}; + +static inline void mxc_init_ide(void) +{ + if (platform_device_register(&mxc_ide_device) < 0) + printk(KERN_ERR "Error: Registering the ide.\n"); +} +#else +static inline void mxc_init_ide(void) +{ +} +#endif + +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) +extern void gpio_ata_active(void); +extern void gpio_ata_inactive(void); + +static int ata_init(struct platform_device *pdev) +{ + /* Configure the pins */ + gpio_ata_active(); + + return 0; +} + +static void ata_exit(void) +{ + /* Free the pins */ + gpio_ata_inactive(); +} + +static struct fsl_ata_platform_data ata_data = { + .udma_mask = ATA_UDMA3, /* board can handle up to UDMA3 */ + .mwdma_mask = ATA_MWDMA2, + .pio_mask = ATA_PIO4, + .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2, + .max_sg = MXC_IDE_DMA_BD_NR, + .init = ata_init, + .exit = ata_exit, + .core_reg = NULL, /*"LDO2", */ + .io_reg = NULL, /*"LDO3", */ +}; + +static struct resource pata_fsl_resources[] = { + [0] = { /* I/O */ + .start = ATA_BASE_ADDR + 0x00, + .end = ATA_BASE_ADDR + 0xD8, + .flags = IORESOURCE_MEM, + }, + [2] = { /* IRQ */ + .start = MXC_INT_ATA, + .end = MXC_INT_ATA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pata_fsl_device = { + .name = "pata_fsl", + .id = -1, + .num_resources = ARRAY_SIZE(pata_fsl_resources), + .resource = pata_fsl_resources, + .dev = { + .platform_data = &ata_data, + .coherent_dma_mask = ~0, + }, +}; + +static void __init mxc_init_pata(void) +{ + (void)platform_device_register(&pata_fsl_device); +} +#else /* CONFIG_PATA_FSL */ +static void __init mxc_init_pata(void) +{ +} +#endif /* CONFIG_PATA_FSL */ + +/*! + * Board specific 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(); +} + /*! * This structure defines static mappings for the i.MX31ADS board. */ @@ -526,20 +1331,126 @@ static void __init mx31ads_init_irq(void) */ static void __init mxc_board_init(void) { + mxc_cpu_common_init(); + early_console_setup(saved_command_line); + mxc_init_devices(); + mxc_init_pmic_audio(); + mxc_register_gpios(); + mx31ads_gpio_init(); + mxc_init_keypad(); mxc_init_extuart(); - mxc_init_imx_uart(); mxc_init_i2c(); + mxc_init_nor_mtd(); + mxc_init_nand_mtd(); + imx_nfc_init(); + + i2c_register_board_info(0, mxc_i2c_info, ARRAY_SIZE(mxc_i2c_info)); + spi_register_board_info(mxc_spi_board_info, + ARRAY_SIZE(mxc_spi_board_info)); + + mxc_init_fb(); + mxc_init_bl(); + mxc_init_ir(); + mxc_init_mmc(); + mxc_init_ide(); + mxc_init_pata(); } static void __init mx31ads_timer_init(void) { - mx31_clocks_init(26000000); + unsigned long ckih = 26000000; + + if ((__raw_readw(PBC_BASE_ADDRESS + PBC_BSTAT) & + CKIH_27MHZ_BIT_SET) != 0) { + ckih = 27000000; + } + + mx31_clocks_init(ckih); } static struct sys_timer mx31ads_timer = { .init = mx31ads_timer_init, }; + +#define PLL_PCTL_REG(pd, mfd, mfi, mfn) \ + ((((pd) - 1) << 26) + (((mfd) - 1) << 16) + ((mfi) << 10) + mfn) + +/* For 26MHz input clock */ +#define PLL_532MHZ PLL_PCTL_REG(1, 13, 10, 3) +#define PLL_399MHZ PLL_PCTL_REG(1, 52, 7, 35) +#define PLL_133MHZ PLL_PCTL_REG(2, 26, 5, 3) + +/* For 27MHz input clock */ +#define PLL_532_8MHZ PLL_PCTL_REG(1, 15, 9, 13) +#define PLL_399_6MHZ PLL_PCTL_REG(1, 18, 7, 7) +#define PLL_133_2MHZ PLL_PCTL_REG(3, 5, 7, 2) + +#define PDR0_REG(mcu, max, hsp, ipg, nfc) \ + (MXC_CCM_PDR0_MCU_DIV_##mcu | MXC_CCM_PDR0_MAX_DIV_##max | \ + MXC_CCM_PDR0_HSP_DIV_##hsp | MXC_CCM_PDR0_IPG_DIV_##ipg | \ + MXC_CCM_PDR0_NFC_DIV_##nfc) + +/* working point(wp): 0 - 133MHz; 1 - 266MHz; 2 - 399MHz; 3 - 532MHz */ +/* 26MHz input clock table */ +static struct cpu_wp cpu_wp_26[] = { + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 133000000, + .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 266000000, + .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 399000000, + .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 532000000, + .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),}, +}; + +/* 27MHz input clock table */ +static struct cpu_wp cpu_wp_27[] = { + { + .pll_reg = PLL_532_8MHZ, + .pll_rate = 532800000, + .cpu_rate = 133200000, + .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),}, + { + .pll_reg = PLL_532_8MHZ, + .pll_rate = 532800000, + .cpu_rate = 266400000, + .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),}, + { + .pll_reg = PLL_399_6MHZ, + .pll_rate = 399600000, + .cpu_rate = 399600000, + .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),}, + { + .pll_reg = PLL_532_8MHZ, + .pll_rate = 532800000, + .cpu_rate = 532800000, + .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),}, +}; + +struct cpu_wp *get_cpu_wp(int *wp) +{ + *wp = 4; + if ((__raw_readw(PBC_BASE_ADDRESS + PBC_BSTAT) & + CKIH_27MHZ_BIT_SET) != 0) { + return cpu_wp_27; + } else { + return cpu_wp_26; + } +} + /* * The following uses standard kernel macros defined in arch.h in order to * initialize __mach_desc_MX31ADS data structure. @@ -549,6 +1460,7 @@ MACHINE_START(MX31ADS, "Freescale MX31ADS") .phys_io = AIPS1_BASE_ADDR, .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, .map_io = mx31ads_map_io, .init_irq = mx31ads_init_irq, .init_machine = mxc_board_init, diff --git a/arch/arm/mach-mx3/mx31ads_gpio.c b/arch/arm/mach-mx3/mx31ads_gpio.c new file mode 100644 index 000000000000..4d63db812804 --- /dev/null +++ b/arch/arm/mach-mx3/mx31ads_gpio.c @@ -0,0 +1,1561 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/gpio.h> +#include "board-mx31ads.h" +#include "iomux.h" + +/*! + * @file mach-mx3/mx31ads_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO_MX31 + */ + +void gpio_activate_audio_ports(void); + +/*! + * This system-wise GPIO function initializes the pins during system startup. + * All the statically linked device drivers should put the proper GPIO initialization + * code inside this function. It is called by \b fixup_mx31ads() during + * system startup. This function is board specific. + */ +void mx31ads_gpio_init(void) +{ + /* config CS4 */ + mxc_request_iomux(MX31_PIN_CS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + /*Connect DAM ports 4 & 5 to enable audio I/O */ + gpio_activate_audio_ports(); +} + +/*! + * Setup GPIO for a UART port to be active + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_active(int port, int no_irda) +{ + unsigned int pbc_bctrl1_clr = 0, pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0; + /* + * Configure the IOMUX control registers for the UART signals + */ + switch (port) { + /* UART 1 IOMUX Configs */ + case 0: + mxc_request_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_DTR_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + /* Enable the transceiver */ + pbc_bctrl1_clr |= PBC_BCTRL1_UENCE; + pbc_bctrl2_set |= PBC_BCTRL2_USELC; + break; + /* UART 2 IOMUX Configs */ + case 1: + mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + if (no_irda == 1) { + mxc_request_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_DTR_DCE2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + pbc_bctrl1_clr |= PBC_BCTRL1_UENCE; + pbc_bctrl2_clr |= PBC_BCTRL2_USELC; + } else { + pbc_bctrl1_clr |= PBC_BCTRL1_IREN; + pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD; + } + break; + /* UART 3 IOMUX Configs */ + case 2: + mxc_request_iomux(MX31_PIN_CSPI3_MOSI, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_MISO, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_SCLK, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_SPI_RDY, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + + pbc_bctrl1_clr |= PBC_BCTRL1_UENB; + pbc_bctrl2_clr |= PBC_BCTRL2_USELB; + break; + /* UART 4 IOMUX Configs */ + case 3: + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + + pbc_bctrl1_clr |= PBC_BCTRL1_UENB; + pbc_bctrl2_set |= PBC_BCTRL2_USELB; + break; + /* UART 5 IOMUX Configs */ + case 4: + mxc_request_iomux(MX31_PIN_PC_VS2, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_PC_RST, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_PC_BVD1, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_PC_BVD2, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + + pbc_bctrl1_clr |= PBC_BCTRL1_UENA; + pbc_bctrl2_set |= PBC_BCTRL2_USELA; + break; + default: + break; + } + + __raw_writew(pbc_bctrl1_clr, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR); + __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + /* + * TODO: Configure the Pad registers for the UART pins + */ +} + +/*! + * Setup GPIO for a UART port to be inactive + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_inactive(int port, int no_irda) +{ + unsigned int pbc_bctrl1_set = 0; + + switch (port) { + case 0: + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RXD1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_TXD1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RTS1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RI_DCE1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), NULL); + + mxc_free_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_DTR_DCE1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + + pbc_bctrl1_set |= PBC_BCTRL1_UENCE; + break; + case 1: + gpio_request(IOMUX_TO_GPIO(MX31_PIN_TXD2), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RXD2), NULL); + + mxc_free_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + + if (no_irda == 1) { + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE2), NULL); + mxc_free_iomux(MX31_PIN_DTR_DCE2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + + pbc_bctrl1_set |= PBC_BCTRL1_UENCE; + } else { + pbc_bctrl1_set |= PBC_BCTRL1_IREN; + } + break; + case 2: + pbc_bctrl1_set |= PBC_BCTRL1_UENB; + break; + case 3: + gpio_request(IOMUX_TO_GPIO(MX31_PIN_ATA_CS0), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_ATA_CS1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW), NULL); + + mxc_free_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + + pbc_bctrl1_set |= PBC_BCTRL1_UENB; + break; + case 4: + pbc_bctrl1_set |= PBC_BCTRL1_UENA; + break; + default: + break; + } + __raw_writew(pbc_bctrl1_set, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); +} + +/*! + * Configure the IOMUX GPR register to receive shared SDMA UART events + * + * @param port a UART port + */ +void config_uartdma_event(int port) +{ + switch (port) { + case 1: + /* Configure to receive UART 2 SDMA events */ + mxc_iomux_set_gpr(MUX_PGP_FIRI, false); + break; + case 2: + /* Configure to receive UART 3 SDMA events */ + mxc_iomux_set_gpr(MUX_CSPI1_UART3, true); + break; + case 4: + /* Configure to receive UART 5 SDMA events */ + mxc_iomux_set_gpr(MUX_CSPI3_UART5_SEL, true); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_uart_active); +EXPORT_SYMBOL(gpio_uart_inactive); +EXPORT_SYMBOL(config_uartdma_event); + +/*! + * Setup GPIO for Keypad to be active + * + */ +void gpio_keypad_active(void) +{ + /* + * Configure the IOMUX control register for keypad signals. + */ + mxc_request_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW4, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW5, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); +} + +EXPORT_SYMBOL(gpio_keypad_active); + +/*! + * Setup GPIO for Keypad to be inactive + * + */ +void gpio_keypad_inactive(void) +{ + mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + + mxc_request_iomux(MX31_PIN_KEY_ROW4, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_ROW5, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_keypad_inactive); + +void gpio_power_key_active(void) +{ +} +EXPORT_SYMBOL(gpio_power_key_active); + +/*! + * Setup GPIO for a CSPI device to be active + * + * @param cspi_mod an CSPI device + */ +void gpio_spi_active(int cspi_mod) +{ + switch (cspi_mod) { + case 0: + /* SPI1 */ + mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 1: + /* SPI2 */ + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 2: + /* SPI3 */ + /* + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + */ + break; + default: + break; + } +} + +/*! + * Setup 1-Wire to be active + */ +void gpio_owire_active(void) +{ + /* + * Configure the IOMUX control register for 1-wire signals. + */ + iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_pad(MX31_PIN_BATT_LINE, PAD_CTL_LOOPBACK); +} + +/*! + * Setup 1-Wire to be active + */ +void gpio_owire_inactive(void) +{ + /* + * Configure the IOMUX control register for 1-wire signals. + */ + iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_owire_active); +EXPORT_SYMBOL(gpio_owire_inactive); + +/*! + * Setup GPIO for a CSPI device to be inactive + * + * @param cspi_mod a CSPI device + */ +void gpio_spi_inactive(int cspi_mod) +{ + /* Do nothing as CSPI pins doesn't have/support GPIO mode */ +} + +/*! + * Setup GPIO for an I2C device to be active + * + * @param i2c_num an I2C device + */ +void gpio_i2c_active(int i2c_num) +{ + switch (i2c_num) { + case 0: + mxc_request_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 1: + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + case 2: + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + default: + break; + } + +} + +/*! + * Setup GPIO for an I2C device to be inactive + * + * @param i2c_num an I2C device + */ +void gpio_i2c_inactive(int i2c_num) +{ + switch (i2c_num) { + case 0: + break; + case 1: + break; + case 2: + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_GPIO, + INPUTCONFIG_ALT1); + break; + default: + break; + } +} + +/*! + * This function configures the IOMux block for PMIC standard operations. + * + */ +void gpio_pmic_active(void) +{ + mxc_request_iomux(MX31_PIN_GPIO1_3, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), NULL); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); +} + +EXPORT_SYMBOL(gpio_pmic_active); + +/*! + * This function activates DAM ports 4 & 5 to enable + * audio I/O. Thsi function is called from mx31ads_gpio_init + * function, which is board-specific. + */ +void gpio_activate_audio_ports(void) +{ + /* config Audio ports (4 & 5) */ + mxc_request_iomux(MX31_PIN_SCK4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SRXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_STXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SFS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SCK5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SRXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_STXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SFS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); +} + +/*! + * Setup GPIO for SDHC to be active + * + * @param module SDHC module number + */ +void gpio_sdhc_active(int module) +{ + switch (module) { + case 0: + mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + break; + case 1: + mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_sdhc_active); + +/*! + * Setup GPIO for SDHC1 to be inactive + * + * @param module SDHC module number + */ +void gpio_sdhc_inactive(int module) +{ + switch (module) { + case 0: + mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + break; + case 1: + /* TODO:what are the pins for SDHC2? */ + mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_sdhc_inactive); + +/* + * Probe for the card. If present the GPIO data would be set. + */ +int sdhc_get_card_det_status(struct device *dev) +{ + if (to_platform_device(dev)->id == 0) { + return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + } else { + return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + } +} + +EXPORT_SYMBOL(sdhc_get_card_det_status); + +/* + * Return the card detect pin. + */ +int sdhc_init_card_det(int id) +{ + if (id == 0) { + iomux_config_mux(MX31_PIN_GPIO1_1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + return IOMUX_TO_IRQ(MX31_PIN_GPIO1_1); + } else { + iomux_config_mux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + return IOMUX_TO_IRQ(MX31_PIN_GPIO1_2); + + } +} + +EXPORT_SYMBOL(sdhc_init_card_det); + +/*! + * Setup GPIO for LCD to be active + * + */ +void gpio_lcd_active(void) +{ + u16 temp; + + mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD16 + mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD17 + mxc_request_iomux(MX31_PIN_VSYNC3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // VSYNC + mxc_request_iomux(MX31_PIN_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // HSYNC + mxc_request_iomux(MX31_PIN_FPSHIFT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLK + mxc_request_iomux(MX31_PIN_DRDY0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // DRDY + mxc_request_iomux(MX31_PIN_D3_REV, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // REV + mxc_request_iomux(MX31_PIN_CONTRAST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CONTR + mxc_request_iomux(MX31_PIN_D3_SPL, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // SPL + mxc_request_iomux(MX31_PIN_D3_CLS, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLS + + temp = PBC_BCTRL1_LCDON; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); +} + +/*! + * Setup GPIO for LCD to be inactive + * + */ +void gpio_lcd_inactive(void) +{ + u16 pbc_bctrl1_set = 0; + + pbc_bctrl1_set = (u16) PBC_BCTRL1_LCDON; + __raw_writew(pbc_bctrl1_set, PBC_BASE_ADDRESS + PBC_BCTRL1_SET + 2); +} + +/*! + * Setup pins for SLCD to be active + * + */ +void slcd_gpio_config(void) +{ + u16 temp; + + /* Reset smart lcd */ + temp = PBC_BCTRL2_LDC_RST0; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + msleep(2); + /* Bring out of reset */ + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + msleep(2); + + mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + mxc_request_iomux(MX31_PIN_READ, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* read */ + mxc_request_iomux(MX31_PIN_WRITE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* write */ + mxc_request_iomux(MX31_PIN_PAR_RS, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* RS */ + mxc_request_iomux(MX31_PIN_LCS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* chip select */ + + /* Enable smart lcd interface */ + temp = PBC_BCTRL2_LDCIO_EN; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); +} + +/*! + * Switch to the specified sensor - MX31 ADS has two + * + */ +void gpio_sensor_select(int sensor) +{ + u16 temp; + + switch (sensor) { + case 0: +#ifdef CONFIG_MXC_CAMERA_MC521DA + temp = 0x100; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); +#else + temp = PBC_BCTRL1_SENSOR2_ON; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR); + temp = PBC_BCTRL1_SENSOR1_ON; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); +#endif + break; + case 1: + temp = PBC_BCTRL1_SENSOR1_ON; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR); + temp = PBC_BCTRL1_SENSOR2_ON; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); + break; + default: + break; + } +} + +/*! + * Setup GPIO for sensor to be active + * + */ +void gpio_sensor_active(void) +{ + gpio_sensor_select(0); + + /* + * Configure the iomuxen for the CSI. + */ + + mxc_request_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + +#ifdef CONFIG_MXC_IPU_CAMERA_16BIT + /* + * The other 4 data bits are multiplexed on MX31. + */ + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_ALT2, + INPUTCONFIG_ALT2); +#endif + + /* + * Now enable the CSI buffers + */ + + __raw_writew(PBC_BCTRL2_CSI_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + +#ifdef CONFIG_MXC_IPU_CAMERA_16BIT + /* + * Enable the other buffer for the additional 4 data bits. + */ + __raw_writew(PBC_BCTRL4_CSI_MSB_EN, + PBC_BASE_ADDRESS + PBC_BCTRL4_CLEAR); +#endif +} + +EXPORT_SYMBOL(gpio_sensor_active); + +void gpio_sensor_reset(bool flag) +{ + u16 temp; + + if (flag) { + temp = 0x200; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR); + } else { + temp = 0x200; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET); + } +} + +EXPORT_SYMBOL(gpio_sensor_reset); + +/*! + * Setup GPIO for sensor to be inactive + * + */ +void gpio_sensor_inactive(void) +{ + mxc_free_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); +} + +EXPORT_SYMBOL(gpio_sensor_inactive); + +/*! + * Setup GPIO for ATA interface + * + */ +void gpio_ata_active(void) +{ + /* + * Configure the GPR for ATA group B signals + */ + __raw_writew(PBC_BCTRL2_ATA_SEL, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + __raw_writew(PBC_BCTRL2_ATA_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + + mxc_iomux_set_gpr(MUX_PGP_ATA_7 | MUX_PGP_ATA_6 | MUX_PGP_ATA_2 | + MUX_PGP_ATA_1, true); + + /* + * Configure the IOMUX for ATA group B signals + */ + + mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D0 + mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D1 + mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D2 + mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D3 + mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D4 + mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D5 + mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D6 + mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D7 + mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D8 + mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D9 + mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D10 + mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D11 + mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D12 + mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D13 + mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D14 + mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D15 + + mxc_request_iomux(MX31_PIN_USBH2_STP, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DMARQ_B + mxc_request_iomux(MX31_PIN_USBH2_CLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_INTRQ_B + mxc_request_iomux(MX31_PIN_USBH2_NXT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA0 + mxc_request_iomux(MX31_PIN_USBH2_DATA0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA1 + mxc_request_iomux(MX31_PIN_USBH2_DATA1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA2 + mxc_request_iomux(MX31_PIN_USBH2_DIR, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_BUFFER_DIR + + /* These ATA pins are common to Group A and Group B */ + + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + /* Need fast slew rate for UDMA mode */ + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 0 + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 1 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 2 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 3 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 4 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 5 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 6 + mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 7 + mxc_iomux_set_pad(MX31_PIN_SRXD3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 8 + mxc_iomux_set_pad(MX31_PIN_SCK3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 9 + mxc_iomux_set_pad(MX31_PIN_SFS3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 10 + mxc_iomux_set_pad(MX31_PIN_STXD6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 11 + mxc_iomux_set_pad(MX31_PIN_SRXD6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 12 + mxc_iomux_set_pad(MX31_PIN_SCK6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 13 + mxc_iomux_set_pad(MX31_PIN_CAPTURE, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 14 + mxc_iomux_set_pad(MX31_PIN_COMPARE, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 12 + + /* + * Turn off default pullups on high asserted control signals. + * These are pulled down externally, so it will just waste + * power and create voltage divider action to pull them up + * on chip. + */ + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, PAD_CTL_PKE_NONE); // ATA_DMARQ + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, PAD_CTL_PKE_NONE); // ATA_INTRQ +} + +EXPORT_SYMBOL(gpio_ata_active); + +/*! + * Restore ATA interface pins to reset values + * + */ +void gpio_ata_inactive(void) +{ + __raw_writew(PBC_BCTRL2_ATA_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + /* + * Turn off ATA group B signals + */ + mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D7 + mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D8 + mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D11 + mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D12 + mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D13 + mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D14 + mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D15 + + /* These ATA pins are common to Group A and Group B */ + + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + + /* Needed fast slew rate for UDMA mode */ + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 0 + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 1 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 2 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 3 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 4 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 5 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 6 + mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 7 + mxc_iomux_set_pad(MX31_PIN_SRXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 8 + mxc_iomux_set_pad(MX31_PIN_SCK3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 9 + mxc_iomux_set_pad(MX31_PIN_SFS3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 10 + mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 11 + mxc_iomux_set_pad(MX31_PIN_SRXD6, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 12 + mxc_iomux_set_pad(MX31_PIN_SCK6, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 13 + mxc_iomux_set_pad(MX31_PIN_CAPTURE, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 14 + mxc_iomux_set_pad(MX31_PIN_COMPARE, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 12 +} + +EXPORT_SYMBOL(gpio_ata_inactive); + +/*! + * Setup EDIO/IOMUX for external UART. + * + * @param port UART port + * @param irq Interrupt line to allocate + * @param handler Function to be called when the IRQ occurs + * @param irq_flags Interrupt type flags + * @param devname An ascii name for the claiming device + * @param dev_id A cookie passed back to the handler function + * @return Returns 0 if the interrupt was successfully requested, + * otherwise returns an error code. + */ +int extuart_intr_setup(unsigned int port, unsigned int irq, + irqreturn_t(*handler) (int, void *), + unsigned long irq_flags, const char *devname, + void *dev_id) +{ + return 0; +} + +/*! + * Get the EDIO interrupt, clear if set. + * + * @param port UART port + */ +void extuart_intr_clear(unsigned int port) +{ +} + +/*! + * Do IOMUX configs required to put the + * pin back in low power mode. + * + * @param port UART port + * @param irq Interrupt line to free + * @param dev_id Device identity to free + * @return Returns 0 if the interrupt was successfully freed, + * otherwise returns an error code. + */ +int extuart_intr_cleanup(unsigned int port, unsigned int irq, void *dev_id) +{ + return 0; +} + +/* *INDENT-OFF* */ +/* + * USB Host 1 + * pins conflict with SPI1, ATA, UART3 + */ +int gpio_usbh1_active(void) +{ + if (mxc_request_iomux(MX31_PIN_CSPI1_MOSI, /* USBH1_RXDM */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_MISO, /* USBH1_RXDP */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_SS0, /* USBH1_TXDM */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_SS1, /* USBH1_TXDP */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_SS2, /* USBH1_RCV */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_SCLK, /* USBH1_OEB (_TXOE) */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, /* USBH1_FS */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1)) { + return -EINVAL; + } + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, /* USBH1_RXDM */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, /* USBH1_RXDP */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, /* USBH1_TXDM */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, /* USBH1_TXDP */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, /* USBH1_RCV */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, /* USBH1_OEB (_TXOE) */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, /* USBH1_FS */ + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true); + + __raw_writew(PBC_BCTRL3_FSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable FSH */ + __raw_writew(PBC_BCTRL3_FSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); /* Group B */ + __raw_writew(PBC_BCTRL3_FSH_MOD, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* single ended */ + __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable FSH VBUS */ + + return 0; +} + +EXPORT_SYMBOL(gpio_usbh1_active); + +void gpio_usbh1_inactive(void) +{ + /* Do nothing as pins don't have/support GPIO mode */ + +} + +EXPORT_SYMBOL(gpio_usbh1_inactive); + +/* + * USB Host 2 + * pins conflict with UART5, PCMCIA + */ +int gpio_usbh2_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBH2_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFWE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFRE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFALE, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFCLE, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFWP_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) || + mxc_request_iomux(MX31_PIN_NFCE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE)) { + return -EINVAL; + } + +#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */ + mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */ + mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */ + mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */ + mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */ + mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */ +#undef H2_PAD_CFG + + mxc_iomux_set_gpr(MUX_PGP_UH2, true); + + __raw_writew(PBC_BCTRL3_HSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); /* enable HSH select */ + __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable HSH */ + + return 0; +} + +EXPORT_SYMBOL(gpio_usbh2_active); + +void gpio_usbh2_inactive(void) +{ + iomux_config_gpr(MUX_PGP_UH2, false); + + iomux_config_pad(MX31_PIN_USBH2_CLK, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_USBH2_DIR, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_USBH2_NXT, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_USBH2_STP, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_USBH2_DATA0, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_USBH2_DATA1, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_SRXD6, /* USBH2_DATA2 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_STXD6, /* USBH2_DATA3 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_SFS3, /* USBH2_DATA4 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_SCK3, /* USBH2_DATA5 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_SRXD3, /* USBH2_DATA6 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + iomux_config_pad(MX31_PIN_STXD3, /* USBH2_DATA7 */ + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + + mxc_free_iomux(MX31_PIN_NFWE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_NFRE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_NFALE, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_NFCLE, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_NFWP_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_NFCE_B, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + + __raw_writew(PBC_BCTRL3_HSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); + __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); +} + +EXPORT_SYMBOL(gpio_usbh2_inactive); + +/* + * USB OTG HS port + */ +int gpio_usbotg_hs_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA2, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA3, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA4, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA5, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA6, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA7, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) { + return -EINVAL; + } + + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + /* enable OTG/HS */ + __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); + /* disable OTG/FS */ + __raw_writew(PBC_BCTRL3_OTG_FS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); + return 0; +} + +EXPORT_SYMBOL(gpio_usbotg_hs_active); + +void gpio_usbotg_hs_inactive(void) +{ + /* Do nothing as pins doesn't have/support GPIO mode */ + +} + +EXPORT_SYMBOL(gpio_usbotg_hs_inactive); + +/* + * USB OTG FS port + */ +int gpio_usbotg_fs_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA2, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA3, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA4, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA5, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA6, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA7, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USB_PWR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) { + return -EINVAL; + } + + /* disable OTG/HS */ + __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); + /* enable OTG/FS */ + __raw_writew(PBC_BCTRL3_OTG_FS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); + +#if defined(CONFIG_MC13783_MXC) + /* Select PMIC transceiver */ + __raw_writew(PBC_BCTRL3_OTG_FS_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); +#endif + return 0; + +} + +EXPORT_SYMBOL(gpio_usbotg_fs_active); + +void gpio_usbotg_fs_inactive(void) +{ + /* Do nothing as pins doesn't have/support GPIO mode */ + +} + +EXPORT_SYMBOL(gpio_usbotg_fs_inactive); +/* *INDENT-ON* */ + +/*! + * Setup GPIO for PCMCIA interface + * + */ +void gpio_pcmcia_active(void) +{ + u16 temp; + + mxc_request_iomux(MX31_PIN_SDBA0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SDBA1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + iomux_config_mux(MX31_PIN_LBA, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_RW, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_EB0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_EB1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_OE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + iomux_config_mux(MX31_PIN_IOIS16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_BVD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_BVD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_POE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_READY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_RST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_RW_B, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_VS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_VS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + iomux_config_mux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + /* PCMCIA VPP, VCC Enable, 1 = power on */ + temp = PBC_BCTRL2_VPP_EN | PBC_BCTRL2_VCC_EN; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + + /* Set up Card2 Select pin for PCMCIA, 0 = PCMCIA & SD2 */ + temp = PBC_BCTRL3_CARD2_SEL; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); + + /* PCMCIA Enable, 0 = enable */ + temp = PBC_BCTRL4_PCMCIA_EN; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL4_CLEAR); + mdelay(1); +} + +EXPORT_SYMBOL(gpio_pcmcia_active); + +/*! + * Setup GPIO for pcmcia to be inactive + */ +void gpio_pcmcia_inactive(void) +{ + u16 temp; + + /* PCMCIA Enable, 0 = enable */ + temp = PBC_BCTRL4_PCMCIA_EN; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL4_SET); + + /* Set up Card2 Select pin for PCMCIA, 0 = PCMCIA & SD2 */ + temp = PBC_BCTRL3_CARD2_SEL; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); + + /* PCMCIA VPP, VCC Enable, 1 = power on */ + temp = PBC_BCTRL2_VPP_EN | PBC_BCTRL2_VCC_EN; + __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); +} + +EXPORT_SYMBOL(gpio_pcmcia_inactive); +/*! + * Setup IR to be used by UART and FIRI + */ +void gpio_firi_init(void) +{ + gpio_uart_active(1, 0); +} + +EXPORT_SYMBOL(gpio_firi_init); + +/*! + * Setup IR to be used by UART + */ +void gpio_firi_inactive(void) +{ + unsigned int pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0; + + iomux_config_gpr(MUX_PGP_FIRI, false); + mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + pbc_bctrl2_set |= PBC_BCTRL2_IRDA_MOD; + __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + + pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD; + __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); +} + +EXPORT_SYMBOL(gpio_firi_inactive); + +/*! + * Setup IR to be used by FIRI + */ +void gpio_firi_active(void *fir_cong_reg_base, unsigned int tpp_mask) +{ + unsigned int pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0; + unsigned int cr; + + iomux_config_gpr(MUX_PGP_FIRI, true); + + cr = readl(fir_cong_reg_base); + cr &= ~tpp_mask; + writel(cr, fir_cong_reg_base); + + pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD; + __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + + pbc_bctrl2_set |= PBC_BCTRL2_IRDA_MOD; + __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET); + + cr = readl(fir_cong_reg_base); + cr |= tpp_mask; + writel(cr, fir_cong_reg_base); + + __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR); + + cr = readl(fir_cong_reg_base); + cr &= ~tpp_mask; + writel(cr, fir_cong_reg_base); +} + +EXPORT_SYMBOL(gpio_firi_active); diff --git a/arch/arm/mach-mx3/mx3_3stack.c b/arch/arm/mach-mx3/mx3_3stack.c new file mode 100644 index 000000000000..5a29b0550509 --- /dev/null +++ b/arch/arm/mach-mx3/mx3_3stack.c @@ -0,0 +1,1075 @@ +/* + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/i2c.h> +#include <linux/nodemask.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/consumer.h> +#include <linux/ata.h> +#include <linux/smsc911x.h> +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach/flash.h> +#endif + +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/keypad.h> +#include <asm/mach/time.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/memory.h> +#include <mach/gpio.h> +#include <mach/mmc.h> +#include <mach/spba.h> +#include <mach/pmic_power.h> + +#include "board-mx3_3stack.h" +#include "crm_regs.h" +#include "iomux.h" +/*! + * @file mach-mx3/mx3_3stack.c + * + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX31 + */ + +extern void mxc_map_io(void); +extern void mxc_init_irq(void); +extern void mxc_cpu_init(void) __init; +extern void mxc_cpu_common_init(void); +extern void __init early_console_setup(char *); +extern int mxc_init_devices(void); + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) +static u16 keymapping[12] = { + KEY_UP, KEY_DOWN, 0, 0, + KEY_RIGHT, KEY_LEFT, KEY_ENTER, 0, + KEY_F6, KEY_F8, KEY_F9, KEY_F10, +}; + +static struct resource mxc_kpp_resources[] = { + [0] = { + .start = MXC_INT_KPP, + .end = MXC_INT_KPP, + .flags = IORESOURCE_IRQ, + } +}; + +static struct keypad_data keypad_plat_data = { + .rowmax = 3, + .colmax = 4, + .irq = MXC_INT_KPP, + .learning = 0, + .delay = 2, + .matrix = keymapping, +}; + +/* mxc keypad driver */ +static struct platform_device mxc_keypad_device = { + .name = "mxc_keypad", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_kpp_resources), + .resource = mxc_kpp_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &keypad_plat_data, + }, +}; + +static void mxc_init_keypad(void) +{ + (void)platform_device_register(&mxc_keypad_device); +} +#else +static inline void mxc_init_keypad(void) +{ +} +#endif + +/* MTD NAND flash */ +#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) + +static struct mtd_partition mxc_nand_partitions[] = { + { + .name = "nand.bootloader", + .offset = 0, + .size = 1024 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 5 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 180 * 1024 * 1024}, + { + .name = "nand.configure", + .offset = MTDPART_OFS_APPEND, + .size = 8 * 1024 * 1024}, + { + .name = "nand.userfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; + +static struct flash_platform_data mxc_nand_data = { + .parts = mxc_nand_partitions, + .nr_parts = ARRAY_SIZE(mxc_nand_partitions), + .width = 1, +}; + +static struct platform_device mxc_nand_mtd_device = { + .name = "mxc_nand_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static struct platform_device mxc_nandv2_mtd_device = { + .name = "mxc_nandv2_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static void mxc_init_nand_mtd(void) +{ + if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) { + mxc_nand_data.width = 2; + } + if (cpu_is_mx31()) { + (void)platform_device_register(&mxc_nand_mtd_device); + } + if (cpu_is_mx32()) { + (void)platform_device_register(&mxc_nandv2_mtd_device); + } +} +#else +static inline void mxc_init_nand_mtd(void) +{ +} +#endif + +static void lcd_reset(void) +{ + /* ensure that LCDIO(1.8V) has been turn on */ + /* active reset line GPIO */ + mxc_request_iomux(MX31_PIN_LCS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS1), "lcs1"); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_LCS1), 0); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_LCS1), 0); + /* do reset */ + msleep(10); /* tRES >= 100us */ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_LCS1), 1); + msleep(60); +#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_LCS1), 0); +#endif +} + +static struct mxc_lcd_platform_data lcd_data = { + .io_reg = "VGEN", +#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL + .core_reg = "GPO1", +#else + .core_reg = "VMMC1", +#endif + .reset = lcd_reset, +}; + +static struct mxc_camera_platform_data camera_data = { + .core_regulator = "VVIB", + .io_regulator = "VMMC1", + .analog_regulator = "SW2B", + .gpo_regulator = "GPO3", + .mclk = 27000000, +}; + +struct mxc_tvout_platform_data tvout_data = { + .io_reg = "VGEN", + .core_reg = "GPO3", + .analog_reg = "GPO1", + .detect_line = 49, +}; + +void si4702_reset(void) +{ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SRST0), 0); + msleep(100); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SRST0), 1); + msleep(100); +} + +void si4702_clock_ctl(int flag) +{ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SIMPD0), flag); +} + +static void si4702_gpio_get(void) +{ + /* reset pin */ + mxc_request_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SRST0), "srst0"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_SRST0), 0); + + mxc_request_iomux(MX31_PIN_SIMPD0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SIMPD0), "simpd0"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_SIMPD0), 0); +} + +static void si4702_gpio_put(void) +{ + mxc_free_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_SIMPD0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); +} + +static struct mxc_fm_platform_data si4702_data = { + .reg_vio = "GPO3", + .reg_vdd = "VMMC1", + .gpio_get = si4702_gpio_get, + .gpio_put = si4702_gpio_put, + .reset = si4702_reset, + .clock_ctl = si4702_clock_ctl, + .sksnr = 0, + .skcnt = 0, + .band = 0, + .space = 100, + .seekth = 0xa, +}; + +/* setup GPIO for mma7450 */ +static void gpio_mma7450_get(void) +{ + mxc_request_iomux(MX31_PIN_STX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_iomux_set_pad(MX31_PIN_STX0, PAD_CTL_PKE_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_STX0), "stx0"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_STX0)); + + mxc_request_iomux(MX31_PIN_SRX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_iomux_set_pad(MX31_PIN_SRX0, PAD_CTL_PKE_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SRX0), "srx0"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SRX0)); +} + +static void gpio_mma7450_put(void) +{ + mxc_free_iomux(MX31_PIN_STX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_SRX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); +} + +static struct mxc_mma7450_platform_data mma7450_data = { + .reg_dvdd_io = "GPO3", + .reg_avdd = "VMMC1", + .gpio_pin_get = gpio_mma7450_get, + .gpio_pin_put = gpio_mma7450_put, + .int1 = IOMUX_TO_IRQ(MX31_PIN_STX0), + .int2 = IOMUX_TO_IRQ(MX31_PIN_SRX0), +}; + +static struct i2c_board_info mxc_i2c_board_info[] __initdata = { + { + .type = "ov2640", + .addr = 0x30, + .platform_data = (void *)&camera_data,}, + { + .type = "ch7024", + .addr = 0x76, + .platform_data = (void *)&tvout_data, + .irq = IOMUX_TO_IRQ(MX31_PIN_BATT_LINE),}, + { + .type = "si4702", + .addr = 0x10, + .platform_data = (void *)&si4702_data, + }, + { + .type = "mma7450", + .addr = 0x1d, + .platform_data = (void *)&mma7450_data, + }, +}; + +static struct spi_board_info mxc_spi_board_info[] __initdata = { + { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .max_speed_hz = 4000000, + .bus_num = 2, + .chip_select = 2, + }, + { + .modalias = "lcd_spi", + .platform_data = (void *)&lcd_data, + .max_speed_hz = 5000000, + .bus_num = 1, + .chip_select = 2, + }, +}; + +/*lan9217 device*/ +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +static struct resource smsc911x_resources[] = { + { + .start = LAN9217_BASE_ADDR, + .end = LAN9217_BASE_ADDR + 0x100, + .flags = IORESOURCE_MEM, + }, + { + .start = LAN9217_IRQ, + .end = LAN9217_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct smsc911x_platform_config smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .flags = SMSC911X_USE_32BIT | 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 void mxc_init_enet(void) +{ + (void)platform_device_register(&smsc_lan9217_device); +} +#else +static inline void mxc_init_enet(void) +{ +} +#endif + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static const char fb_default_mode[] = "Epson-VGA"; + +/* mxc lcd driver */ +static struct platform_device mxc_fb_device = { + .name = "mxc_sdc_fb", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &fb_default_mode, + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +static struct platform_device mxc_fb_wvga_device = { + .name = "lcd_claa", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &lcd_data, + }, +}; + +static void mxc_init_fb(void) +{ + (void)platform_device_register(&mxc_fb_device); + (void)platform_device_register(&mxc_fb_wvga_device); +} +#else +static inline void mxc_init_fb(void) +{ +} +#endif + +#if defined(CONFIG_BACKLIGHT_MXC) +static struct platform_device mxcbl_devices[] = { +#if defined(CONFIG_BACKLIGHT_MXC_IPU) || defined(CONFIG_BACKLIGHT_MXC_IPU_MODULE) + { + .name = "mxc_ipu_bl", + .id = 0, + .dev = { + .platform_data = (void *)3, /* DISP # for this backlight */ + }, + }, +#endif +}; +static inline void mxc_init_bl(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) { + platform_device_register(&mxcbl_devices[i]); + } +} +#else +static inline void mxc_init_bl(void) +{ +} +#endif + +#if defined(CONFIG_FB_MXC_TVOUT_CH7024) || \ + defined(CONFIG_FB_MXC_TVOUT_CH7024_MODULE) +static int mxc_init_ch7024(void) +{ + /* request gpio for phone jack detect */ + mxc_request_iomux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_iomux_set_pad(MX31_PIN_BATT_LINE, PAD_CTL_PKE_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_BATT_LINE), "batt_line"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_BATT_LINE)); + + return 0; +} +#else +static inline int mxc_init_ch7024(void) +{ + return 0; +} +#endif + +static u32 brd_io; + +static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 imr_val; + u32 int_valid; + u32 expio_irq; + + desc->chip->mask(irq); /* irq = gpio irq number */ + + imr_val = __raw_readw(brd_io + INTR_MASK_REG); + int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + + if (unlikely(!int_valid)) { + goto out; + } + + expio_irq = MXC_BOARD_IRQ_START; + for (; int_valid != 0; int_valid >>= 1, expio_irq++) { + struct irq_desc *d; + if ((int_valid & 1) == 0) + continue; + d = irq_desc + expio_irq; + if (unlikely(!(d->handle_irq))) { + printk(KERN_ERR "\nEXPIO irq: %d unhandled\n", + expio_irq); + BUG(); /* oops */ + } + d->handle_irq(expio_irq, d); + } + + out: + desc->chip->ack(irq); + desc->chip->unmask(irq); +} + +/* + * Disable an expio pin's interrupt by setting the bit in the imr. + * @param irq an expio virtual irq number + */ +static void expio_mask_irq(u32 irq) +{ + u16 reg; + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* mask the interrupt */ + reg = __raw_readw(brd_io + INTR_MASK_REG); + reg |= (1 << expio); + __raw_writew(reg, brd_io + INTR_MASK_REG); +} + +/* + * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. + * @param irq an expanded io virtual irq number + */ +static void expio_ack_irq(u32 irq) +{ + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* clear the interrupt status */ + __raw_writew(1 << expio, brd_io + INTR_RESET_REG); + __raw_writew(0, brd_io + INTR_RESET_REG); + /* mask the interrupt */ + expio_mask_irq(irq); +} + +/* + * Enable a expio pin's interrupt by clearing the bit in the imr. + * @param irq a expio virtual irq number + */ +static void expio_unmask_irq(u32 irq) +{ + u16 reg; + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* unmask the interrupt */ + reg = __raw_readw(brd_io + INTR_MASK_REG); + reg &= ~(1 << expio); + __raw_writew(reg, brd_io + INTR_MASK_REG); +} + +static struct irq_chip expio_irq_chip = { + .ack = expio_ack_irq, + .mask = expio_mask_irq, + .unmask = expio_unmask_irq, +}; + +static int __init mxc_expio_init(void) +{ + int i; + + brd_io = (u32) ioremap(BOARD_IO_ADDR, SZ_4K); + if (brd_io == 0) + return -ENOMEM; + + if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + iounmap((void *)brd_io); + brd_io = 0; + return -ENODEV; + } + + pr_info("3-Stack Debug board detected, rev = 0x%04X\n", + readw(brd_io + CPLD_CODE_VER_REG)); + + /* + * Configure INT line as GPIO input + */ + mxc_request_iomux(MX31_PIN_GPIO1_1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "gpio1_1"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1)); + + /* disable the interrupt and clear the status */ + __raw_writew(0, brd_io + INTR_MASK_REG); + __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); + __raw_writew(0, brd_io + INTR_RESET_REG); + __raw_writew(0x1F, brd_io + INTR_MASK_REG); + for (i = MXC_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(EXPIO_PARENT_INT, IRQF_TRIGGER_LOW); + set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler); + + return 0; +} + +#if (defined(CONFIG_MXC_PMIC_MC13783) || \ + defined(CONFIG_MXC_PMIC_MC13783_MODULE)) \ + && (defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE)) +static void __init mxc_init_pmic_audio(void) +{ + struct clk *ckih_clk; + struct clk *cko_clk; + + /* Enable 26 mhz clock on CKO1 for PMIC audio */ + ckih_clk = clk_get(NULL, "ckih"); + cko_clk = clk_get(NULL, "cko1_clk"); + if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) { + printk(KERN_ERR "Unable to set CKO1 output to CKIH\n"); + } else { + clk_set_parent(cko_clk, ckih_clk); + clk_set_rate(cko_clk, clk_get_rate(ckih_clk)); + clk_enable(cko_clk); + } + clk_put(ckih_clk); + clk_put(cko_clk); + + /* config Audio ports (4 & 5) */ + mxc_request_iomux(MX31_PIN_SCK4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SRXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_STXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SFS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SCK5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SRXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_STXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SFS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); +} +#else +static void __inline mxc_init_pmic_audio(void) +{ +} +#endif + +/* MMC device data */ + +#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE) +static struct mxc_mmc_platform_data mmc1_data = { + .ocr_mask = MMC_VDD_32_33, + .min_clk = 150000, + .max_clk = 25000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .power_mmc = "GPO1", +}; + +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc1_resources[] = { + [0] = { + .start = MMC_SDHC1_BASE_ADDR, + .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC1, + .end = MXC_INT_MMC_SDHC1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mxc_mmc_platform_data mmc2_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | + MMC_VDD_31_32, + .min_clk = 150000, + .max_clk = 25000000, + .card_fixed = 1, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .power_mmc = "VMMC2", +}; + +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc2_resources[] = { + [0] = { + .start = MMC_SDHC2_BASE_ADDR, + .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC2, + .end = MXC_INT_MMC_SDHC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC1 */ +static struct platform_device mxcsdhc1_device = { + .name = "mxcmci", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc1_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc1_resources), + .resource = mxcsdhc1_resources, +}; + +/*! Device Definition for MXC SDHC2 */ +static struct platform_device mxcsdhc2_device = { + .name = "mxcmci", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc2_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc2_resources), + .resource = mxcsdhc2_resources, +}; + +static inline void mxc_init_mmc(void) +{ + int cd_irq; + + cd_irq = sdhc_init_card_det(0); + if (cd_irq) { + mxcsdhc1_device.resource[2].start = cd_irq; + mxcsdhc1_device.resource[2].end = cd_irq; + } + + cd_irq = sdhc_init_card_det(1); + if (cd_irq) { + mxcsdhc2_device.resource[2].start = cd_irq; + mxcsdhc2_device.resource[2].end = cd_irq; + } + + spba_take_ownership(SPBA_SDHC1, SPBA_MASTER_A | SPBA_MASTER_C); + (void)platform_device_register(&mxcsdhc1_device); + + spba_take_ownership(SPBA_SDHC2, SPBA_MASTER_A | SPBA_MASTER_C); + (void)platform_device_register(&mxcsdhc2_device); +} +#else +static inline void mxc_init_mmc(void) +{ +} +#endif + +/*! + * Board specific fixup function. It is called by \b setup_arch() in + * setup.c file very early on during kernel starts. It allows the user to + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mxc_cpu_init(); + +#ifdef CONFIG_DISCONTIGMEM + do { + int nid; + mi->nr_banks = MXC_NUMNODES; + for (nid = 0; nid < mi->nr_banks; nid++) { + SET_NODE(mi, nid); + } + } while (0); +#endif +} + +/* IDE device data */ +#if defined(CONFIG_BLK_DEV_IDE_MXC) || defined(CONFIG_BLK_DEV_IDE_MXC_MODULE) + +/*! Platform Data for MXC IDE */ +static struct mxc_ide_platform_data mxc_ide_data = { + .power_drive = "GPO2", + .power_io = "GPO3", +}; + +static struct platform_device mxc_ide_device = { + .name = "mxc_ide", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_ide_data, + }, +}; + +static inline void mxc_init_ide(void) +{ + if (platform_device_register(&mxc_ide_device) < 0) + printk(KERN_ERR "Error: Registering the ide.\n"); +} +#else +static inline void mxc_init_ide(void) +{ +} +#endif + +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) +extern void gpio_ata_active(void); +extern void gpio_ata_inactive(void); + +static int ata_init(struct platform_device *pdev) +{ + /* Configure the pins */ + gpio_ata_active(); + + return 0; +} + +static void ata_exit(void) +{ + /* Free the pins */ + gpio_ata_inactive(); +} + +static struct fsl_ata_platform_data ata_data = { + .udma_mask = ATA_UDMA3, /* board can handle up to UDMA3 */ + .mwdma_mask = ATA_MWDMA2, + .pio_mask = ATA_PIO4, + .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2, + .max_sg = MXC_IDE_DMA_BD_NR, + .init = ata_init, + .exit = ata_exit, + .core_reg = "GPO2", /*"LDO2", */ + .io_reg = "GPO3", /*"LDO3", */ +}; + +static struct resource pata_fsl_resources[] = { + [0] = { /* I/O */ + .start = ATA_BASE_ADDR + 0x00, + .end = ATA_BASE_ADDR + 0xD8, + .flags = IORESOURCE_MEM, + }, + [2] = { /* IRQ */ + .start = MXC_INT_ATA, + .end = MXC_INT_ATA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pata_fsl_device = { + .name = "pata_fsl", + .id = -1, + .num_resources = ARRAY_SIZE(pata_fsl_resources), + .resource = pata_fsl_resources, + .dev = { + .platform_data = &ata_data, + .coherent_dma_mask = ~0, + }, +}; + +static void __init mxc_init_pata(void) +{ + (void)platform_device_register(&pata_fsl_device); +} +#else /* CONFIG_PATA_FSL */ +static void __init mxc_init_pata(void) +{ +} +#endif /* CONFIG_PATA_FSL */ + +static void bt_reset(void) +{ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), 1); +} + +static struct mxc_bt_platform_data mxc_bt_data = { + .bt_vdd = "VMMC2", + .bt_vdd_parent = "GPO1", + .bt_vusb = NULL, + .bt_vusb_parent = "GPO3", + .bt_reset = bt_reset, +}; + +static struct platform_device mxc_bt_device = { + .name = "mxc_bt", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_bt_data, + }, +}; + +static void mxc_init_bluetooth(void) +{ + (void)platform_device_register(&mxc_bt_device); +} + +static void mxc_unifi_hardreset(int pin_level) +{ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), pin_level & 0x01); +} + +static struct mxc_unifi_platform_data unifi_data = { + .hardreset = mxc_unifi_hardreset, + + /* GPO3 -> enables SW2B 1.8V out - this becomes 1V8 on personality + * board, then 1V8_EXT, then BT_VUSB + */ + .reg_gpo1 = "GPO3", + + /* GPO4 -> WiFi_PWEN, but this signal is not used on current boards */ + .reg_gpo2 = "GPO4", + + .reg_1v5_ana_bb = "VRF1", /* VRF1 -> WL_1V5ANA and WL_1V5BB */ + .reg_vdd_vpa = "VMMC2", /* VMMC2 -> WL_VDD and WL_VPA */ + .reg_1v5_dd = "VRF2", /* VRF2 -> WL_1V5DD */ + + .host_id = 1, +}; + +struct mxc_unifi_platform_data *get_unifi_plat_data(void) +{ + return &unifi_data; +} + +EXPORT_SYMBOL(get_unifi_plat_data); + +#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE) +static struct mxc_gps_platform_data gps_data = { + .core_reg = "GPO3", + .analog_reg = "GPO1", +}; + +static struct platform_device mxc_gps_device = { + .name = "gps_ioctrl", + .id = -1, + .dev = { + .platform_data = &gps_data, + }, +}; + +static void __init mxc_init_gps(void) +{ + (void)platform_device_register(&mxc_gps_device); +} +#else +static void __init mxc_init_gps(void) +{ +} +#endif + +static void __init mx3_3stack_timer_init(void) +{ + mx31_clocks_init(26000000); +} + +static struct sys_timer mxc_timer = { + .init = mx3_3stack_timer_init, +}; + +/*! + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + /* config CS5 for debug board */ + mxc_request_iomux(MX31_PIN_CS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + mxc_cpu_common_init(); + mxc_register_gpios(); + early_console_setup(saved_command_line); + mxc_init_devices(); + + /*Pull down MX31_PIN_USB_BYP to reset USB3317 */ + mxc_request_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), "usb_byp"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), 0); + mxc_free_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + + /* Reset BT/WiFi chip */ + mxc_request_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), "dcd_dce1"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1), 0); + + mxc_init_pmic_audio(); + mxc_expio_init(); + mxc_init_keypad(); + mxc_init_enet(); + mxc_init_nand_mtd(); + mxc_init_ch7024(); + mx3_3stack_init_mc13783(); + + i2c_register_board_info(0, mxc_i2c_board_info, + ARRAY_SIZE(mxc_i2c_board_info)); + spi_register_board_info(mxc_spi_board_info, + ARRAY_SIZE(mxc_spi_board_info)); + + mxc_init_fb(); + mxc_init_bl(); + mxc_init_mmc(); + mxc_init_ide(); + mxc_init_pata(); + mxc_init_bluetooth(); + mxc_init_gps(); +} + +#define PLL_PCTL_REG(pd, mfd, mfi, mfn) \ + ((((pd) - 1) << 26) + (((mfd) - 1) << 16) + ((mfi) << 10) + mfn) + +/* For 26MHz input clock */ +#define PLL_532MHZ PLL_PCTL_REG(1, 13, 10, 3) +#define PLL_399MHZ PLL_PCTL_REG(1, 52, 7, 35) +#define PLL_133MHZ PLL_PCTL_REG(2, 26, 5, 3) + +#define PDR0_REG(mcu, max, hsp, ipg, nfc) \ + (MXC_CCM_PDR0_MCU_DIV_##mcu | MXC_CCM_PDR0_MAX_DIV_##max | \ + MXC_CCM_PDR0_HSP_DIV_##hsp | MXC_CCM_PDR0_IPG_DIV_##ipg | \ + MXC_CCM_PDR0_NFC_DIV_##nfc) + +/* working point(wp): 0 - 133MHz; 1 - 266MHz; 2 - 399MHz; 3 - 532MHz */ +/* 26MHz input clock table */ +static struct cpu_wp cpu_wp_26[] = { + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 133000000, + .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 266000000, + .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 399000000, + .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 532000000, + .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),}, +}; + +struct cpu_wp *get_cpu_wp(int *wp) +{ + *wp = 4; + return cpu_wp_26; +} + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX3_3STACK data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX31_3DS, "Freescale MX31/MX32 3-Stack Board") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mx31_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx3/mx3_3stack_gpio.c b/arch/arm/mach-mx3/mx3_3stack_gpio.c new file mode 100644 index 000000000000..41e0b692bf37 --- /dev/null +++ b/arch/arm/mach-mx3/mx3_3stack_gpio.c @@ -0,0 +1,1311 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/pmic_adc.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/gpio.h> +#include "board-mx3_3stack.h" +#include "iomux.h" + +/*! + * @file mach-mx3/mx3_3stack_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO_MX31 + */ + +/*! + * Setup GPIO for a UART port to be active + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_active(int port, int no_irda) +{ + /* + * Configure the IOMUX control registers for the UART signals + */ + switch (port) { + /* UART 1 IOMUX Configs */ + case 0: + mxc_request_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + /* UART 2 IOMUX Configs */ + case 1: + mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + mxc_request_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + /* UART 3 IOMUX Configs */ + case 2: + mxc_request_iomux(MX31_PIN_CSPI3_MOSI, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_MISO, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_SCLK, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI3_SPI_RDY, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + default: + break; + } + + /* + * TODO: Configure the Pad registers for the UART pins + */ +} + +/*! + * Setup GPIO for a UART port to be inactive + * + * @param port a UART port + * @param no_irda indicates if the port is used for SIR + */ +void gpio_uart_inactive(int port, int no_irda) +{ + switch (port) { + case 0: + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RXD1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_TXD1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RTS1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), NULL); + + mxc_free_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + break; + case 1: + gpio_request(IOMUX_TO_GPIO(MX31_PIN_TXD2), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_RXD2), NULL); + + mxc_free_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + default: + break; + } +} + +/*! + * Configure the IOMUX GPR register to receive shared SDMA UART events + * + * @param port a UART port + */ +void config_uartdma_event(int port) +{ + switch (port) { + case 1: + /* Configure to receive UART 2 SDMA events */ + mxc_iomux_set_gpr(MUX_PGP_FIRI, false); + break; + case 2: + /* Configure to receive UART 3 SDMA events */ + mxc_iomux_set_gpr(MUX_CSPI1_UART3, true); + break; + case 4: + /* Configure to receive UART 5 SDMA events */ + mxc_iomux_set_gpr(MUX_CSPI3_UART5_SEL, true); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_uart_active); +EXPORT_SYMBOL(gpio_uart_inactive); +EXPORT_SYMBOL(config_uartdma_event); + +/*! + * Setup GPIO for Keypad to be active + * + */ +void gpio_keypad_active(void) +{ + /* + * Configure the IOMUX control register for keypad signals. + */ + mxc_request_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); +} + +EXPORT_SYMBOL(gpio_keypad_active); + +/*! + * Setup GPIO for Keypad to be inactive + * + */ +void gpio_keypad_inactive(void) +{ + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_COL0), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_COL1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_COL2), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_COL3), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_ROW0), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_ROW1), NULL); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_KEY_ROW2), NULL); + + mxc_free_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_keypad_inactive); + +void gpio_power_key_active(void) +{ + mxc_request_iomux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), NULL); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); + mxc_iomux_set_pad(MX31_PIN_GPIO1_2, PAD_CTL_PKE_NONE); +} + +EXPORT_SYMBOL(gpio_power_key_active); + +/*! + * Setup GPIO for a CSPI device to be active + * + * @param cspi_mod an CSPI device + */ +void gpio_spi_active(int cspi_mod) +{ + switch (cspi_mod) { + case 0: + /* SPI1 */ + /* setup GPR for CSPI BB */ + iomux_config_gpr(MUX_PGP_CSPI_BB, true); + /* CSPI1 clock and RDY use full UART ALT1 mode */ + mxc_request_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + case 1: + /* SPI2 */ + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 2: + /* SPI3 */ + /* + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + */ + break; + default: + break; + } +} + +/*! + * Setup 1-Wire to be active + */ +void gpio_owire_active(void) +{ + /* + * Configure the IOMUX control register for 1-wire signals. + */ + iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + iomux_config_pad(MX31_PIN_BATT_LINE, PAD_CTL_LOOPBACK); +} + +/*! + * Setup 1-Wire to be active + */ +void gpio_owire_inactive(void) +{ + /* + * Configure the IOMUX control register for 1-wire signals. + */ + iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_owire_active); +EXPORT_SYMBOL(gpio_owire_inactive); + +/*! + * Setup GPIO for a CSPI device to be inactive + * + * @param cspi_mod a CSPI device + */ +void gpio_spi_inactive(int cspi_mod) +{ + switch (cspi_mod) { + case 0: + /* SPI1 */ + /* setup GPR for CSPI BB */ + iomux_config_gpr(MUX_PGP_CSPI_BB, false); + /* CSPI1 clock and RDY use full UART ALT1 mode */ + mxc_free_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 1: + /* SPI2 */ + mxc_free_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 2: + /* SPI3 */ + break; + default: + break; + } +} + +/*! + * Setup GPIO for an I2C device to be active + * + * @param i2c_num an I2C device + */ +void gpio_i2c_active(int i2c_num) +{ + switch (i2c_num) { + case 0: + mxc_request_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 1: + mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + case 2: + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + default: + break; + } + +} + +/*! + * Setup GPIO for an I2C device to be inactive + * + * @param i2c_num an I2C device + */ +void gpio_i2c_inactive(int i2c_num) +{ + switch (i2c_num) { + case 0: + mxc_free_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + break; + case 1: + mxc_free_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, + INPUTCONFIG_ALT1); + mxc_free_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, + INPUTCONFIG_ALT1); + break; + case 2: + mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_ALT1); + break; + default: + break; + } +} + +/*! + * This function configures the IOMux block for PMIC standard operations. + * + */ +void gpio_pmic_active(void) +{ + mxc_request_iomux(MX31_PIN_GPIO1_3, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), NULL); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)); +} + +EXPORT_SYMBOL(gpio_pmic_active); + +/*! + * Setup GPIO for SDHC to be active + * + * @param module SDHC module number + */ +void gpio_sdhc_active(int module) +{ + switch (module) { + case 0: + mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, + (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST + | PAD_CTL_100K_PU)); + + /* + * Active the Buffer Enable Pin only if there is + * a card in slot. + * To fix the card voltage issue caused by + * bi-directional chip TXB0108 on 3Stack + */ + if (gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1))) + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 0); + else + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 1); + break; + case 1: + mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_ALT1, + INPUTCONFIG_ALT1); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_sdhc_active); + +/*! + * Setup GPIO for SDHC1 to be inactive + * + * @param module SDHC module number + */ +void gpio_sdhc_inactive(int module) +{ + switch (module) { + case 0: + mxc_free_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + mxc_iomux_set_pad(MX31_PIN_SD1_CLK, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_CMD, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW)); + + /* Buffer Enable Pin of SD, Active HI */ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 0); + break; + case 1: + /* TODO:what are the pins for SDHC2? */ + mxc_free_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_FUNC, + INPUTCONFIG_NONE); + break; + default: + break; + } +} + +EXPORT_SYMBOL(gpio_sdhc_inactive); + +/* + * Probe for the card. If present the GPIO data would be set. + */ +unsigned int sdhc_get_card_det_status(struct device *dev) +{ + int ret; + + if (to_platform_device(dev)->id == 0) { + ret = gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); + /* + * Active the Buffer Enable Pin only if there is + * a card in slot. + * To fix the card voltage issue caused by + * bi-directional chip TXB0108 on 3Stack + */ + if (ret) + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 0); + else + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 1); + return ret; + } else + return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); +} + +EXPORT_SYMBOL(sdhc_get_card_det_status); + +/* + * Return the card detect pin. + */ +int sdhc_init_card_det(int id) +{ + if (id == 0) { + /* Buffer Enable Pin, Active HI */ + mxc_request_iomux(MX31_PIN_GPIO3_0, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), "gpio3_0"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_GPIO3_0), 0); + + /* CD Pin */ + mxc_request_iomux(MX31_PIN_GPIO3_1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + mxc_iomux_set_pad(MX31_PIN_GPIO3_1, PAD_CTL_PKE_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "gpio3_1"); + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)); + return IOMUX_TO_IRQ(MX31_PIN_GPIO3_1); + } else { + iomux_config_mux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + return IOMUX_TO_IRQ(MX31_PIN_GPIO1_2); + + } +} + +EXPORT_SYMBOL(sdhc_init_card_det); + +/*! + * Get SD1_WP ADIN7 of ATLAS pin value to detect write protection + */ +int sdhc_write_protect(struct device *dev) +{ + unsigned short rc = 0; + + pmic_adc_convert(GEN_PURPOSE_AD7, &rc); + if (rc > 0) + return 1; + else + return 0; +} + +EXPORT_SYMBOL(sdhc_write_protect); + +/*! + * Setup GPIO for LCD to be active + * + */ +void gpio_lcd_active(void) +{ + + mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD16 + mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD17 + mxc_request_iomux(MX31_PIN_VSYNC3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // VSYNC + mxc_request_iomux(MX31_PIN_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // HSYNC + mxc_request_iomux(MX31_PIN_FPSHIFT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLK + mxc_request_iomux(MX31_PIN_CONTRAST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CONTR + +#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL + mxc_request_iomux(MX31_PIN_DRDY0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* DRDY */ + mxc_request_iomux(MX31_PIN_D3_REV, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* REV */ + mxc_request_iomux(MX31_PIN_D3_SPL, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* SPL */ + mxc_request_iomux(MX31_PIN_D3_CLS, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* CLS */ +#else + /* ensure that LCDIO(1.8V) has been turn on */ + /* active reset line GPIO */ + mxc_request_iomux(MX31_PIN_LCS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS1), "lcs1"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_LCS1), 0); + /* do reset */ + mdelay(10); /* tRES >= 100us */ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_LCS1), 1); + + /* enable data */ + mxc_request_iomux(MX31_PIN_SER_RS, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SER_RS), "ser_rs"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_SER_RS), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SER_RS), 1); +#endif +} + +/*! + * Setup GPIO for LCD to be inactive + * + */ +void gpio_lcd_inactive(void) +{ + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SER_RS), 0); +} + +/*! + * Switch to the specified sensor - MX31 ADS has two + * + */ +void gpio_sensor_select(int sensor) +{ +} + +/*! + * Setup GPIO for sensor to be active + * + */ +void gpio_sensor_active(void) +{ + gpio_sensor_select(0); + + /* + * Configure the iomuxen for the CSI. + */ + + mxc_request_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "csi_d5"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 0); + + mxc_request_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + + if (mxc_request_iomux(MX31_PIN_A23, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) + == 0) { + printk(KERN_ERR "%s:REGEN set request gpio ok\n", __func__); + } else { + printk(KERN_ERR "%s:REGEN set error, request gpio error\n", + __func__); + return; + } + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SD_D_IO), "sd_d_io"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_SD_D_IO), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SD_D_IO), 1); +} + +EXPORT_SYMBOL(gpio_sensor_active); + +void gpio_sensor_reset(bool flag) +{ +} + +EXPORT_SYMBOL(gpio_sensor_reset); + +/*! + * Setup GPIO for sensor to be inactive + * + */ +void gpio_sensor_inactive(void) +{ + mxc_free_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_free_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); +} + +EXPORT_SYMBOL(gpio_sensor_inactive); + +/*! + * Setup GPIO for ATA interface + * + */ +void gpio_ata_active(void) +{ + /* + * Configure the GPR for ATA group B signals + */ + mxc_iomux_set_gpr(MUX_PGP_ATA_8 | MUX_PGP_ATA_5 | MUX_PGP_ATA_4 | + MUX_PGP_ATA_3 | MUX_PGP_ATA_2, false); + + mxc_iomux_set_gpr(MUX_PGP_ATA_9 | MUX_PGP_ATA_7 | MUX_PGP_ATA_6 | + MUX_PGP_ATA_1, true); + + /* + * Configure the IOMUX for ATA group B signals + */ + + mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D0 + mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D1 + mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D2 + mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D3 + mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D4 + mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D5 + mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D6 + mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D7 + mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D8 + mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D9 + mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D10 + mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D11 + mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D12 + mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D13 + mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D14 + mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D15 + + /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */ + mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DMARQ_B + mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_INTRQ_B + mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA0 + mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA1 + mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA2 + mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_BUFFER_DIR + + /* HDD_ENABLE_B(H:Disable,L:Enable) */ + mxc_request_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); // HDD_ENABLE_B + gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D4), "csi_d4"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D4), 0); + mdelay(10); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D4), 0); + mdelay(10); + + /* These ATA pins are common to Group A and Group B */ + + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_FUNC, + INPUTCONFIG_FUNC); + mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); + + /* Need fast slew rate for UDMA mode */ + +#define ATA_DAT_PAD_CFG (PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE | PAD_CTL_100K_PU) + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, ATA_DAT_PAD_CFG); // data 0 + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, ATA_DAT_PAD_CFG); // data 1 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, ATA_DAT_PAD_CFG); // data 2 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, ATA_DAT_PAD_CFG); // data 3 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, ATA_DAT_PAD_CFG); // data 4 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, ATA_DAT_PAD_CFG); // data 5 + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, ATA_DAT_PAD_CFG); // data 6 + mxc_iomux_set_pad(MX31_PIN_STXD3, ATA_DAT_PAD_CFG); // data 7 + mxc_iomux_set_pad(MX31_PIN_SRXD3, ATA_DAT_PAD_CFG); // data 8 + mxc_iomux_set_pad(MX31_PIN_SCK3, ATA_DAT_PAD_CFG); // data 9 + mxc_iomux_set_pad(MX31_PIN_SFS3, ATA_DAT_PAD_CFG); // data 10 + mxc_iomux_set_pad(MX31_PIN_STXD6, ATA_DAT_PAD_CFG); // data 11 + mxc_iomux_set_pad(MX31_PIN_SRXD6, ATA_DAT_PAD_CFG); // data 12 + mxc_iomux_set_pad(MX31_PIN_SCK6, ATA_DAT_PAD_CFG); // data 13 + mxc_iomux_set_pad(MX31_PIN_CAPTURE, ATA_DAT_PAD_CFG); // data 14 + mxc_iomux_set_pad(MX31_PIN_COMPARE, ATA_DAT_PAD_CFG); // data 15 +#undef ATA_DAT_PAD_CFG + +#define ATA_CTL_PAD_CFG (PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE) + mxc_iomux_set_pad(MX31_PIN_KEY_COL4, ATA_CTL_PAD_CFG); // ATA_DMARQ); + mxc_iomux_set_pad(MX31_PIN_KEY_ROW6, ATA_CTL_PAD_CFG); // ATA_INTRQ); + mxc_iomux_set_pad(MX31_PIN_KEY_COL5, ATA_CTL_PAD_CFG); // + mxc_iomux_set_pad(MX31_PIN_KEY_COL6, ATA_CTL_PAD_CFG); // + mxc_iomux_set_pad(MX31_PIN_KEY_COL7, ATA_CTL_PAD_CFG); // + mxc_iomux_set_pad(MX31_PIN_KEY_ROW7, ATA_CTL_PAD_CFG); // + + mxc_iomux_set_pad(MX31_PIN_ATA_CS0, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_CS1, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DIOR, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DIOW, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DMACK, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_RESET_B, ATA_CTL_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_PWMO, ATA_CTL_PAD_CFG); +#undef ATA_CTL_PAD_CFG +} + +EXPORT_SYMBOL(gpio_ata_active); + +/*! + * Restore ATA interface pins to reset values + * + */ +void gpio_ata_inactive(void) +{ + /* + * Turn off ATA group B signals + */ + mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D0 + mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D1 + mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D2 + mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D3 + mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D4 + mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D5 + mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D6 + mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D7 + mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D8 + mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D9 + mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D10 + mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D11 + mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D12 + mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D13 + mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D14 + mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D15 + + /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */ + mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DMARQ_B + mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_INTRQ_B + mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA0 + mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA1 + mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA2 + mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_BUFFER_DIR + + /* HDD_BUFF_EN (H:A->B, L:B->A) and HDD_ENABLE_B(H:Disable,L:Enable) */ + mxc_free_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + + /* These ATA pins are common to Group A and Group B */ + + mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + + /* Needed fast slew rate for UDMA mode */ + +#define ATA_DAT_PAD_CFG (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_NORMAL | PAD_CTL_PKE_NONE) + mxc_iomux_set_pad(MX31_PIN_KEY_COL4, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_KEY_ROW6, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_KEY_COL5, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_KEY_COL6, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_KEY_COL7, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_KEY_ROW7, ATA_DAT_PAD_CFG); + + mxc_iomux_set_pad(MX31_PIN_ATA_CS0, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_CS1, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DIOR, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DIOW, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_DMACK, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_ATA_RESET_B, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_PWMO, ATA_DAT_PAD_CFG); + + mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD3, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD3, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK3, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS3, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD6, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK6, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_CAPTURE, ATA_DAT_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_COMPARE, ATA_DAT_PAD_CFG); +#undef ATA_DAT_PAD_CFG +} + +EXPORT_SYMBOL(gpio_ata_inactive); + +/* *INDENT-OFF* */ +/* + * USB Host 1 + * pins conflict with SPI1, ATA, UART3 + */ +int gpio_usbh1_active(void) +{ + return 0; +} + +EXPORT_SYMBOL(gpio_usbh1_active); + +void gpio_usbh1_inactive(void) +{ + /* Do nothing as pins don't have/support GPIO mode */ + +} + +EXPORT_SYMBOL(gpio_usbh1_inactive); + +/* + * USB Host 2 + * pins conflict with UART5, PCMCIA + */ +int gpio_usbh2_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBH2_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBH2_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) || + mxc_request_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */ + OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1)) { + return -EINVAL; + } + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | + PAD_CTL_PKE_NONE)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_VS2, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_BVD1, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_BVD2, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_RST, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_IOIS16, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_RW_B, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + mxc_request_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO, + INPUTCONFIG_NONE); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), "usb_byp"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), 0); + mdelay(1); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_USB_BYP), 1); + return 0; +} + +EXPORT_SYMBOL(gpio_usbh2_active); + +void gpio_usbh2_inactive(void) +{ + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_VS2, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_BVD1, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_BVD2, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_RST, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_IOIS16, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_PC_RW_B, + (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST)); + + mxc_free_iomux(MX31_PIN_USBH2_CLK, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_USBH2_DIR, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_USBH2_NXT, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_USBH2_STP, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_USBH2_DATA0, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_USBH2_DATA1, + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + + mxc_free_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + mxc_free_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); + + mxc_free_iomux(MX31_PIN_USB_BYP, /* USBH2 PHY reset */ + OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); +} + +EXPORT_SYMBOL(gpio_usbh2_inactive); + +/* + * USB OTG HS port + */ +int gpio_usbotg_hs_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA2, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA3, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA4, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA5, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA6, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA7, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) { + return -EINVAL; + } + + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, + (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)); + + /* reset transceiver */ + mxc_request_iomux(MX31_PIN_USB_PWR, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_USB_PWR), "usb_pwr"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_USB_PWR), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_USB_PWR), 0); + mdelay(1); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_USB_PWR), 1); + + return 0; +} + +EXPORT_SYMBOL(gpio_usbotg_hs_active); + +void gpio_usbotg_hs_inactive(void) +{ + mxc_free_iomux(MX31_PIN_USB_PWR, OUTPUTCONFIG_GPIO, + INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_usbotg_hs_inactive); + +/*! + * USB OTG FS port + */ +int gpio_usbotg_fs_active(void) +{ + if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA1, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA2, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA3, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA4, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA5, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA6, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DATA7, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_CLK, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_DIR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_NXT, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USBOTG_STP, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) || + mxc_request_iomux(MX31_PIN_USB_PWR, + OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) + return -EINVAL; + return 0; +} + +EXPORT_SYMBOL(gpio_usbotg_fs_active); + +void gpio_usbotg_fs_inactive(void) +{ + /* Do nothing as pins doesn't have/support GPIO mode */ + +} + +EXPORT_SYMBOL(gpio_usbotg_fs_inactive); + +/*! + * GPS GPIO + */ +void gpio_gps_active(void) +{ + /* POWER_EN */ + mxc_request_iomux(MX31_PIN_SCLK0, + OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_SCLK0), "sclk0"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_SCLK0), 0); + /* Reset Pin */ + mxc_request_iomux(MX31_PIN_DCD_DTE1, + OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + gpio_request(IOMUX_TO_GPIO(MX31_PIN_DCD_DTE1), "dcd_dte1"); + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DCD_DTE1), 0); + + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_SCLK0), 0); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_DCD_DTE1), 0); + + msleep(5); + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_DCD_DTE1), 1); + msleep(5); +} + +EXPORT_SYMBOL(gpio_gps_active); + +int gpio_gps_access(int para) +{ + iomux_pin_name_t pin; + pin = (para & 0x1) ? MX31_PIN_SCLK0 : MX31_PIN_DCD_DTE1; + + if (para & 0x4) /* Read GPIO */ + return gpio_get_value(IOMUX_TO_GPIO(pin)); + else if (para & 0x2) /* Write GPIO */ + gpio_set_value(IOMUX_TO_GPIO(pin), 1); + else + gpio_set_value(IOMUX_TO_GPIO(pin), 0); + return 0; +} + +EXPORT_SYMBOL(gpio_gps_access); + +void gpio_gps_inactive(void) +{ + mxc_free_iomux(MX31_PIN_DCD_DTE1, + OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); + mxc_free_iomux(MX31_PIN_SCLK0, + OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); +} + +EXPORT_SYMBOL(gpio_gps_inactive); diff --git a/arch/arm/mach-mx3/mx3_3stack_pmic_mc13783.c b/arch/arm/mach-mx3/mx3_3stack_pmic_mc13783.c new file mode 100644 index 000000000000..69c5d3ed8a6f --- /dev/null +++ b/arch/arm/mach-mx3/mx3_3stack_pmic_mc13783.c @@ -0,0 +1,272 @@ +/* + * mx3-3stack-pmic-mc13783.c -- i.MX3 3STACK Driver for Atlas MC13783 PMIC + */ + /* + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + + /* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/err.h> +#include <linux/pmic_external.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/mc13783/core.h> +#include <mach/irqs.h> +#include "iomux.h" + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) + +struct mc13783; + +static struct regulator_init_data violo_init = { + .constraints = { + .min_uV = mV_to_uV(1200), /* mc13783 allows min of 1200. */ + .max_uV = mV_to_uV(1800), /* mc13783 allows max of 1800. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vdig_init = { + .constraints = { + .min_uV = mV_to_uV(1200), /* mc13783 allows min of 1200. */ + .max_uV = mV_to_uV(1800), /* mc13783 allows max of 1800. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vgen_init = { + .constraints = { + .min_uV = mV_to_uV(1100), /* mc13783 allows min of 1100. */ + .max_uV = mV_to_uV(2775), /* mc13783 allows max of 2775. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vrfdig_init = { + .constraints = { + .min_uV = mV_to_uV(1200), /* mc13783 allows min of 1200. */ + .max_uV = mV_to_uV(1875), /* mc13783 allows max of 1875. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vrfref_init = { + .constraints = { + .min_uV = mV_to_uV(2475), /* mc13783 allows min of 2475. */ + .max_uV = mV_to_uV(2775), /* mc13783 allows max of 2775. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vrfcp_init = { + .constraints = { + .min_uV = mV_to_uV(2700), /* mc13783 allows min of 2700. */ + .max_uV = mV_to_uV(2775), /* mc13783 allows max of 2775. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vsim_init = { + .constraints = { + .min_uV = mV_to_uV(1800), /* mc13783 allows min of 1800. */ + .max_uV = mV_to_uV(2900), /* mc13783 allows max of 2900. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vesim_init = { + .constraints = { + .min_uV = mV_to_uV(1800), /* mc13783 allows min of 1800. */ + .max_uV = mV_to_uV(2900), /* mc13783 allows max of 2900. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vcam_init = { + .constraints = { + .min_uV = mV_to_uV(1500), /* mc13783 allows min of 1500. */ + .max_uV = mV_to_uV(3000), /* mc13783 allows max of 3000. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vvib_init = { + .constraints = { + .min_uV = mV_to_uV(1300), /* mc13783 allows min of 1300. */ + .max_uV = mV_to_uV(3000), /* mc13783 allows max of 3000. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vrf_init = { + .constraints = { + .min_uV = mV_to_uV(1500), /* mc13783 allows min of 1500. */ + .max_uV = mV_to_uV(2775), /* mc13783 allows max of 2775. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vmmc_init = { + .constraints = { + .min_uV = mV_to_uV(1600), /* mc13783 allows min of 1600. */ + .max_uV = mV_to_uV(3000), /* mc13783 allows max of 3000. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data sw3_init = { + .constraints = { + .min_uV = mV_to_uV(5000), /* mc13783 allows min of 5000. */ + .max_uV = mV_to_uV(5500), /* mc13783 allows max of 5500. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data sw1_init = { + .constraints = { + .min_uV = mV_to_uV(1200), /* mc13783 allows min of 900. */ + .max_uV = mV_to_uV(1600), /* mc13783 allows max of 2200. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_FAST + | REGULATOR_MODE_NORMAL + | REGULATOR_MODE_IDLE + | REGULATOR_MODE_STANDBY, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = mV_to_uV(1250), + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + } +}; + +static struct regulator_init_data sw_init = { + .constraints = { + .min_uV = mV_to_uV(1200), /* mc13783 allows min of 900. */ + .max_uV = mV_to_uV(2200), /* mc13783 allows max of 2200. */ + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vaudio_init = { + .constraints = { + .boot_on = 1, + } +}; + +static struct regulator_init_data viohi_init = { + .constraints = { + .boot_on = 1, + } +}; + +static struct regulator_init_data gpo1_init = { + .constraints = { + .boot_on = 1, + } +}; + +static struct regulator_init_data gpo4_init = { + .constraints = { + }, +}; + +static struct regulator_init_data gpo_init = { + .constraints = { + }, +}; + +static int mc13783_regulator_init(void *data) +{ + struct mc13783 *mc13783 = data; + unsigned int value; + + /*most regulators are controled by standby signal*/ + /*except violo*/ + pmic_read_reg(REG_REGULATOR_MODE_0, &value, 0xffffff); + value |= 0x492412; + pmic_write_reg(REG_REGULATOR_MODE_0, value, 0xffffff); + pmic_read_reg(REG_REGULATOR_MODE_1, &value, 0xffffff); + value |= 0x492492; + pmic_write_reg(REG_REGULATOR_MODE_1, value, 0xffffff); + /*also sw3 is controled by standby signal*/ + pmic_read_reg(REG_SWITCHERS_5, &value, 0xffffff); + value |= 0x200000; + pmic_write_reg(REG_SWITCHERS_5, value, 0xffffff); + + mc13783_register_regulator(mc13783, MC13783_SW1A, &sw1_init); + mc13783_register_regulator(mc13783, MC13783_SW1B, &sw_init); + mc13783_register_regulator(mc13783, MC13783_SW2A, &sw_init); + mc13783_register_regulator(mc13783, MC13783_SW2B, &sw_init); + mc13783_register_regulator(mc13783, MC13783_SW3, &sw3_init); + mc13783_register_regulator(mc13783, MC13783_VMMC1, &vmmc_init); + mc13783_register_regulator(mc13783, MC13783_VMMC2, &vmmc_init); + mc13783_register_regulator(mc13783, MC13783_VVIB, &vvib_init); + mc13783_register_regulator(mc13783, MC13783_VIOHI, &viohi_init); + mc13783_register_regulator(mc13783, MC13783_VIOLO, &violo_init); + mc13783_register_regulator(mc13783, MC13783_VDIG, &vdig_init); + mc13783_register_regulator(mc13783, MC13783_VRFDIG, &vrfdig_init); + mc13783_register_regulator(mc13783, MC13783_VRFREF, &vrfref_init); + mc13783_register_regulator(mc13783, MC13783_VRFCP, &vrfcp_init); + mc13783_register_regulator(mc13783, MC13783_VRF1, &vrf_init); + mc13783_register_regulator(mc13783, MC13783_VRF2, &vrf_init); + mc13783_register_regulator(mc13783, MC13783_VAUDIO, &vaudio_init); + mc13783_register_regulator(mc13783, MC13783_VCAM, &vcam_init); + mc13783_register_regulator(mc13783, MC13783_VGEN, &vgen_init); + mc13783_register_regulator(mc13783, MC13783_VSIM, &vsim_init); + mc13783_register_regulator(mc13783, MC13783_VESIM, &vesim_init); + mc13783_register_regulator(mc13783, MC13783_GPO1, &gpo1_init); + + gpo_init.supply_regulator_dev = &(mc13783->pmic.pdev[MC13783_GPO1]->dev); + mc13783_register_regulator(mc13783, MC13783_GPO2, &gpo_init); + mc13783_register_regulator(mc13783, MC13783_GPO3, &gpo_init); + mc13783_register_regulator(mc13783, MC13783_GPO4, &gpo4_init); + + return 0; +} + +static struct pmic_platform_data mc13783_plat = { + .init = mc13783_regulator_init, + .power_key_irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2), +}; + +static struct spi_board_info __initdata mc13783_spi_device = { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .max_speed_hz = 4000000, + .bus_num = 2, + .platform_data = &mc13783_plat, + .chip_select = 2, +}; + +int __init mx3_3stack_init_mc13783(void) +{ + return spi_register_board_info(&mc13783_spi_device, 1); +} diff --git a/arch/arm/mach-mx3/mxc_pm.c b/arch/arm/mach-mx3/mxc_pm.c new file mode 100644 index 000000000000..97bfba956922 --- /dev/null +++ b/arch/arm/mach-mx3/mxc_pm.c @@ -0,0 +1,440 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @defgroup DPM_MX31 Power Management + * @ingroup MSL_MX31 + */ +/*! + * @file mach-mx3/mxc_pm.c + * + * @brief This file provides all the kernel level and user level API + * definitions for the CRM_MCU and DPLL in mx3. + * + * @ingroup DPM_MX31 + */ + +/* + * Include Files + */ +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <mach/hardware.h> +#include <mach/system.h> +#include <mach/mxc_pm.h> +#include <asm/cacheflush.h> +#include <asm/irq.h> +#include <mach/common.h> +#include <asm/hardware/cache-l2x0.h> + +#include "crm_regs.h" + +/* Local defines */ +#define FREQ_COMP_TOLERANCE 200 /* tolerance percentage times 100 */ +#define MCU_PLL_MAX_FREQ 600000000 /* Maximum frequency MCU PLL clock */ +#define MCU_PLL_MIN_FREQ 160000000 /* Minimum frequency MCU PLL clock */ +#define NFC_MAX_FREQ 20000000 /* Maximum frequency NFC clock */ +#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */ + +static struct clk *mcu_pll_clk; +static struct clk *cpu_clk; +static struct clk *ahb_clk; +static struct clk *ipg_clk; + +/*! + * Spinlock to protect CRM register accesses + */ +static DEFINE_SPINLOCK(mxc_crm_lock); + +/*! + * This function is called to modify the contents of a CCM_MCU register + * + * @param reg_offset the CCM_MCU register that will read + * @param mask the mask to be used to clear the bits that are to be modified + * @param data the data that should be written to the register + */ +void mxc_ccm_modify_reg(void *reg_offset, unsigned int mask, + unsigned int data) +{ + unsigned long flags; + unsigned long reg; + + spin_lock_irqsave(&mxc_crm_lock, flags); + reg = __raw_readl(reg_offset); + reg = (reg & (~mask)) | data; + __raw_writel(reg, reg_offset); + spin_unlock_irqrestore(&mxc_crm_lock, flags); +} + +/*! + * Compare two frequences using allowable tolerance + * + * The MX3 PLL can generate many frequencies. This function + * compares the generated frequency to the requested frequency + * and determines it they are within and acceptable tolerance. + * + * @param freq1 desired frequency + * @param freq2 generated frequency + * + * @return Returns 0 is frequencies are within talerance + * and non-zero is they are not. + */ +static int freq_equal(unsigned long freq1, unsigned long freq2) +{ + if (freq1 > freq2) { + return (freq1 - freq2) <= (freq1 / FREQ_COMP_TOLERANCE); + } + return (freq2 - freq1) <= (freq1 / FREQ_COMP_TOLERANCE); +} + +/*! + * Calculate new MCU clock dividers for the PDR0 regiser. + * + * @param mcu_main_clk PLL output frequency (Hz) + * @param arm_freq desired ARM frequency (Hz) + * @param max_freq desired MAX frequency (Hz) + * @param ip_freq desired IP frequency (Hz) + * @param mask were to return PDR0 mask + * @param value were to return PDR0 value + * + * @return Returns 0 on success or + * Returns non zero if error + * PLL_LESS_ARM_ERR if pll frequency is less than + * desired core frequency + * FREQ_OUT_OF_RANGE if desided frequencies ar not + * possible with the current mcu pll frequency. + */ +static int +cal_pdr0_value(unsigned long mcu_main_clk, + long arm_freq, + long max_freq, + long ip_freq, unsigned long *mask, unsigned long *value) +{ + unsigned long arm_div; /* ARM core clock divider */ + unsigned long max_div; /* MAX clock divider */ + unsigned long ipg_div; /* IPG clock divider */ + unsigned long nfc_div; /* NFC (Nand Flash Controller) clock divider */ + unsigned long hsp_div; /* HSP clock divider */ + + if (arm_freq > mcu_main_clk) { + return -PLL_LESS_ARM_ERR; + } + + arm_div = mcu_main_clk / arm_freq; + if ((arm_div == 0) || !freq_equal(arm_freq, mcu_main_clk / arm_div)) { + return FREQ_OUT_OF_RANGE; + } + max_div = mcu_main_clk / max_freq; + if ((max_div == 0) || !freq_equal(max_freq, mcu_main_clk / max_div)) { + return FREQ_OUT_OF_RANGE; + } + hsp_div = max_div; + + ipg_div = max_freq / ip_freq; + if ((ipg_div == 0) || !freq_equal(ip_freq, max_freq / ipg_div)) { + return FREQ_OUT_OF_RANGE; + } + + nfc_div = ((max_freq - 1000000) / NFC_MAX_FREQ) + 1; + + /* All of the divider values have been calculated. + * Now change the hardware register. */ + + *mask = MXC_CCM_PDR0_HSP_PODF_MASK | + MXC_CCM_PDR0_NFC_PODF_MASK | + MXC_CCM_PDR0_IPG_PODF_MASK | + MXC_CCM_PDR0_MAX_PODF_MASK | MXC_CCM_PDR0_MCU_PODF_MASK; + + *value = ((hsp_div - 1) << MXC_CCM_PDR0_HSP_PODF_OFFSET) | + ((nfc_div - 1) << MXC_CCM_PDR0_NFC_PODF_OFFSET) | + ((ipg_div - 1) << MXC_CCM_PDR0_IPG_PODF_OFFSET) | + ((max_div - 1) << MXC_CCM_PDR0_MAX_PODF_OFFSET) | + ((arm_div - 1) << MXC_CCM_PDR0_MCU_PODF_OFFSET); + + return 0; +} + +/*! + * Integer clock scaling + * + * Change main arm clock frequencies without changing the PLL. + * The integer dividers are changed to produce the desired + * frequencies. The number of valid frequency are limited and + * are determined by the current MCU PLL frequency + * + * @param arm_freq desired ARM frequency (Hz) + * @param max_freq desired MAX frequency (Hz) + * @param ip_freq desired IP frequency (Hz) + * + * @return Returns 0 on success or + * Returns non zero if error + * PLL_LESS_ARM_ERR if pll frequency is less than + * desired core frequency + * FREQ_OUT_OF_RANGE if desided frequencies ar not + * possible with the current mcu pll frequency. + */ +int mxc_pm_intscale(long arm_freq, long max_freq, long ip_freq) +{ + unsigned long mcu_main_clk; /* mcu clock domain main clock */ + unsigned long mask; + unsigned long value; + int ret_value; + + printk(KERN_INFO "arm_freq=%ld, max_freq=%ld, ip_freq=%ld\n", + arm_freq, max_freq, ip_freq); + //print_frequencies(); /* debug */ + + mcu_main_clk = clk_get_rate(mcu_pll_clk); + ret_value = cal_pdr0_value(mcu_main_clk, arm_freq, max_freq, ip_freq, + &mask, &value); + if ((arm_freq != clk_round_rate(cpu_clk, arm_freq)) || + (max_freq != clk_round_rate(ahb_clk, max_freq)) || + (ip_freq != clk_round_rate(ipg_clk, ip_freq))) { + return -EINVAL; + } + + if ((max_freq != clk_get_rate(ahb_clk)) || + (ip_freq != clk_get_rate(ipg_clk))) { + return -EINVAL; + } + + if (arm_freq != clk_get_rate(cpu_clk)) { + ret_value = clk_set_rate(cpu_clk, arm_freq); + } + return ret_value; +} + +/*! + * PLL clock scaling + * + * Change MCU PLL frequency and adjust derived clocks. Integer + * dividers are used generate the derived clocks so changed to produce + * the desired the valid frequencies are limited by the desired ARM + * frequency. + * + * The clock source for the MCU is set to the MCU PLL. + * + * @param arm_freq desired ARM frequency (Hz) + * @param max_freq desired MAX frequency (Hz) + * @param ip_freq desired IP frequency (Hz) + * + * @return Returns 0 on success or + * Returns non zero if error + * PLL_LESS_ARM_ERR if pll frequency is less than + * desired core frequency + * FREQ_OUT_OF_RANGE if desided frequencies ar not + * possible with the current mcu pll frequency. + */ +int mxc_pm_pllscale(long arm_freq, long max_freq, long ip_freq) +{ + signed long pll_freq = 0; /* target pll frequency */ + unsigned long old_pll; + unsigned long mask; + unsigned long value; + int ret_value; + + printk(KERN_INFO "arm_freq=%ld, max_freq=%ld, ip_freq=%ld\n", + arm_freq, max_freq, ip_freq); + //print_frequencies(); + + do { + pll_freq += arm_freq; + if ((pll_freq > MCU_PLL_MAX_FREQ) || (pll_freq / 8 > arm_freq)) { + return FREQ_OUT_OF_RANGE; + } + if (pll_freq < MCU_PLL_MIN_FREQ) { + ret_value = 111; + } else { + ret_value = + cal_pdr0_value(pll_freq, arm_freq, max_freq, + ip_freq, &mask, &value); + } + } while (ret_value != 0); + + old_pll = clk_get_rate(mcu_pll_clk); + if (pll_freq > old_pll) { + /* if pll freq is increasing then change dividers first */ + mxc_ccm_modify_reg(MXC_CCM_PDR0, mask, value); + ret_value = clk_set_rate(mcu_pll_clk, pll_freq); + } else { + /* if pll freq is decreasing then change pll first */ + ret_value = clk_set_rate(mcu_pll_clk, pll_freq); + mxc_ccm_modify_reg(MXC_CCM_PDR0, mask, value); + } + //print_frequencies(); + return ret_value; +} + +/*! + * Implementing steps required to transition to low-power modes + * + * @param mode The desired low-power mode. Possible values are, + * WAIT_MODE, DOZE_MODE, STOP_MODE or DSM_MODE + * + */ +void mxc_pm_lowpower(int mode) +{ + unsigned int lpm; + int enable_flag; + unsigned long reg; + + local_irq_disable(); + enable_flag = 0; + + switch (mode) { + case STOP_MODE: + /* State Retention mode */ + lpm = 2; + /* Disable timer interrupt */ + disable_irq(MXC_INT_GPT); + enable_flag = 1; + + /* Enable Well Bias and set VSTBY + * VSTBY pin will be asserted during SR mode. This asks the + * PM IC to set the core voltage to the standby voltage + * Must clear the MXC_CCM_CCMR_SBYCS bit as well */ + mxc_ccm_modify_reg(MXC_CCM_CCMR, + MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY | + MXC_CCM_CCMR_SBYCS, + MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY | + MXC_CCM_CCMR_SBYCS); + + mxc_ccm_modify_reg(MXC_CCM_CCMR, + MXC_CCM_CCMR_LPM_MASK, + lpm << MXC_CCM_CCMR_LPM_OFFSET); + cpu_do_idle(); + break; + + case DSM_MODE: + /* Deep Sleep Mode */ + lpm = 3; + /* Disable timer interrupt */ + disable_irq(MXC_INT_GPT); + enable_flag = 1; + /* Enabled Well Bias + * SBYCS = 0, MCU clock source is disabled*/ + mxc_ccm_modify_reg(MXC_CCM_CCMR, + MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY | + MXC_CCM_CCMR_SBYCS | MXC_CCM_CCMR_LPM_MASK, + MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY | + MXC_CCM_CCMR_SBYCS | + (lpm << MXC_CCM_CCMR_LPM_OFFSET)); + + /* wake up by keypad */ + reg = __raw_readl(MXC_CCM_WIMR); + reg &= ~(1 << 18); + __raw_writel(reg, MXC_CCM_WIMR); + + flush_cache_all(); + l2x0_disable(); + + mxc_pm_arch_entry(IO_ADDRESS(MX31_NFC_BASE_ADDR), 2048); + printk(KERN_INFO "Resume from DSM\n"); + + l2x0_enable(); + mxc_init_irq(); + + break; + default: + case WAIT_MODE: + /* Wait is the default mode used when idle. */ + reg = __raw_readl(MXC_CCM_CCMR); + reg &= ~MXC_CCM_CCMR_LPM_MASK; + __raw_writel(reg, MXC_CCM_CCMR); + break; + } + + if (enable_flag) { + /* Enable timer interrupt */ + enable_irq(MXC_INT_GPT); + } + local_irq_enable(); +} + +#ifdef CONFIG_MXC_DVFS +/*! + * Changes MCU frequencies using dvfs. + * + * @param armfreq desired ARM frequency in Hz + * @param ahbfreq desired AHB frequency in Hz + * @param ipfreq desired IP frequency in Hz + * + * @return Returns 0 on success, non-zero on error + */ +int mxc_pm_dvfs(unsigned long armfreq, long ahbfreq, long ipfreq) +{ + int ret_value; + int i; + + if (ahbfreq != 133000000) { + return FREQ_OUT_OF_RANGE; + } + if (ipfreq != 66500000) { + return FREQ_OUT_OF_RANGE; + } + ret_value = FREQ_OUT_OF_RANGE; + for (i = 0; i < dvfs_states_tbl->num_of_states; i++) { + if (dvfs_states_tbl->freqs[i] == armfreq) { + ret_value = dvfs_set_state(i); + break; + } + } + + return ret_value; +} +#endif /* CONFIG_MXC_DVFS */ + +/*! + * This function is used to load the module. + * + * @return Returns an Integer on success + */ +static int __init mxc_pm_init_module(void) +{ + printk(KERN_INFO "Low-Level PM Driver module loaded\n"); + + mcu_pll_clk = clk_get(NULL, "mcu_pll"); + cpu_clk = clk_get(NULL, "cpu_clk"); + ahb_clk = clk_get(NULL, "ahb_clk"); + ipg_clk = clk_get(NULL, "ipg_clk"); + return 0; +} + +/*! + * This function is used to unload the module + */ +static void __exit mxc_pm_cleanup_module(void) +{ + clk_put(mcu_pll_clk); + clk_put(cpu_clk); + clk_put(ahb_clk); + clk_put(ipg_clk); + printk(KERN_INFO "Low-Level PM Driver module Unloaded\n"); +} + +module_init(mxc_pm_init_module); +module_exit(mxc_pm_cleanup_module); + +EXPORT_SYMBOL(mxc_pm_intscale); +EXPORT_SYMBOL(mxc_pm_pllscale); +EXPORT_SYMBOL(mxc_pm_lowpower); +#ifdef CONFIG_MXC_DVFS +EXPORT_SYMBOL(mxc_pm_dvfs); +#endif + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MX3 Low-level Power Management Driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-mx3/pm.c b/arch/arm/mach-mx3/pm.c new file mode 100644 index 000000000000..68b692283070 --- /dev/null +++ b/arch/arm/mach-mx3/pm.c @@ -0,0 +1,103 @@ +/* + * linux/arch/arm/mach-mx3/pm.c + * + * MX3 Power Management Routines + * + * Original code for the SA11x0: + * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> + * + * Modified for the PXA250 by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Modified for the OMAP1510 by David Singleton: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> + * + * Modified for the MX31 + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/suspend.h> +#include <linux/regulator/machine.h> +#include <mach/mxc_pm.h> + +/* + * TODO: whatta save? + */ + +static int mx31_suspend_enter(suspend_state_t state) +{ + printk(KERN_INFO "Hi, from mx31_pm_enter\n"); + switch (state) { + case PM_SUSPEND_MEM: + mxc_pm_lowpower(DSM_MODE); + break; + case PM_SUSPEND_STANDBY: + mxc_pm_lowpower(STOP_MODE); + break; + default: + return -1; + } + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int mx31_suspend_prepare(void) +{ + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static void mx31_suspend_finish(void) +{ + return; +} + +static int mx31_pm_valid(suspend_state_t state) +{ + return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX); +} + +struct platform_suspend_ops mx31_suspend_ops = { + .valid = mx31_pm_valid, + .prepare = mx31_suspend_prepare, + .enter = mx31_suspend_enter, + .finish = mx31_suspend_finish, +}; + +static int __init mx31_pm_init(void) +{ + printk(KERN_INFO "Power Management for Freescale MX31\n"); + suspend_set_ops(&mx31_suspend_ops); + + return 0; +} + +late_initcall(mx31_pm_init); diff --git a/arch/arm/mach-mx3/sdma_script_code.h b/arch/arm/mach-mx3/sdma_script_code.h new file mode 100644 index 000000000000..627b896f91a1 --- /dev/null +++ b/arch/arm/mach-mx3/sdma_script_code.h @@ -0,0 +1,581 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __SDMA_SCRIPT_CODE_H__ +#define __SDMA_SCRIPT_CODE_H__ + +/*! +* Following define start address of start script +*/ +#define start_ADDR 0 +/*! +* Following define size of start script +*/ +#define start_SIZE 21 + +/*! +* Following define start address of core script +*/ +#define core_ADDR 80 +/*! +* Following define size of core script +*/ +#define core_SIZE 152 + +/*! +* Following define start address of common script +*/ +#define common_ADDR 232 +/*! +* Following define size of common script +*/ +#define common_SIZE 191 + +/*! +* Following define start address of burst_copy script +*/ +#define burst_copy_ADDR 423 +/*! +* Following define size of burst_copy script +*/ +#define burst_copy_SIZE 87 + +/*! +* Following define start address of dsp_2_burst script +*/ +#define dsp_2_burst_ADDR 510 +/*! +* Following define size of dsp_2_burst script +*/ +#define dsp_2_burst_SIZE 24 + +/*! +* Following define start address of burst_2_dsp script +*/ +#define burst_2_dsp_ADDR 534 +/*! +* Following define size of burst_2_dsp script +*/ +#define burst_2_dsp_SIZE 24 + +/*! +* Following define start address of dsp_copy script +*/ +#define dsp_copy_ADDR 558 +/*! +* Following define size of dsp_copy script +*/ +#define dsp_copy_SIZE 86 + +/*! +* Following define start address of mcu_2_mcu script +*/ +#define mcu_2_mcu_ADDR 644 +/*! +* Following define size of mcu_2_mcu script +*/ +#define mcu_2_mcu_SIZE 79 + +/*! +* Following define start address of mcu_2_per script +*/ +#define mcu_2_per_ADDR 723 +/*! +* Following define size of mcu_2_per script +*/ +#define mcu_2_per_SIZE 88 + +/*! +* Following define start address of test script +*/ +#define test_ADDR 811 +/*! +* Following define size of test script +*/ +#define test_SIZE 63 + +/*! +* Following define start address of mcu_2_dsp script +*/ +#define mcu_2_dsp_ADDR 874 +/*! +* Following define size of mcu_2_dsp script +*/ +#define mcu_2_dsp_SIZE 30 + +/*! +* Following define start address of mcu_2_dsp_2buf script +*/ +#define mcu_2_dsp_2buf_ADDR 904 +/*! +* Following define size of mcu_2_dsp_2buf script +*/ +#define mcu_2_dsp_2buf_SIZE 113 + +/*! +* Following define start address of dsp_2_mcu script +*/ +#define dsp_2_mcu_ADDR 1017 +/*! +* Following define size of dsp_2_mcu script +*/ +#define dsp_2_mcu_SIZE 30 + +/*! +* Following define start address of dsp_2_mcu_2buf script +*/ +#define dsp_2_mcu_2buf_ADDR 1047 +/*! +* Following define size of dsp_2_mcu_2buf script +*/ +#define dsp_2_mcu_2buf_SIZE 113 + +/*! +* Following define start address of dsp_2_dsp script +*/ +#define dsp_2_dsp_ADDR 1160 +/*! +* Following define size of dsp_2_dsp script +*/ +#define dsp_2_dsp_SIZE 64 + +/*! +* Following define start address of per_2_mcu script +*/ +#define per_2_mcu_ADDR 1224 +/*! +* Following define size of per_2_mcu script +*/ +#define per_2_mcu_SIZE 121 + +/*! +* Following define start address of dsp_2_per_2buf script +*/ +#define dsp_2_per_2buf_ADDR 1345 +/*! +* Following define size of dsp_2_per_2buf script +*/ +#define dsp_2_per_2buf_SIZE 164 + +/*! +* Following define start address of per_2_dsp_2buf script +*/ +#define per_2_dsp_2buf_ADDR 1509 +/*! +* Following define size of per_2_dsp_2buf script +*/ +#define per_2_dsp_2buf_SIZE 168 + +/*! +* Following define start address of per_2_per script +*/ +#define per_2_per_ADDR 1677 +/*! +* Following define size of per_2_per script +*/ +#define per_2_per_SIZE 67 + +/*! +* Following define start address of error_dsp script +*/ +#define error_dsp_ADDR 1744 +/*! +* Following define size of error_dsp script +*/ +#define error_dsp_SIZE 34 + +/*! +* Following define start address of ap_2_ap script +*/ +#define ap_2_ap_ADDR 6144 +/*! +* Following define size of ap_2_ap script +*/ +#define ap_2_ap_SIZE 294 + +/*! +* Following define start address of app_2_mcu script +*/ +#define app_2_mcu_ADDR 6438 +/*! +* Following define size of app_2_mcu script +*/ +#define app_2_mcu_SIZE 101 + +/*! +* Following define start address of ata_2_mcu script +*/ +#define ata_2_mcu_ADDR 6539 +/*! +* Following define size of ata_2_mcu script +*/ +#define ata_2_mcu_SIZE 110 + +/*! +* Following define start address of dptc_dvfs script +*/ +#define dptc_dvfs_ADDR 6649 +/*! +* Following define size of dptc_dvfs script +*/ +#define dptc_dvfs_SIZE 274 + +/*! +* Following define start address of error script +*/ +#define error_ADDR 6923 +/*! +* Following define size of error script +*/ +#define error_SIZE 73 + +/*! +* Following define start address of firi_2_mcu script +*/ +#define firi_2_mcu_ADDR 6996 +/*! +* Following define size of firi_2_mcu script +*/ +#define firi_2_mcu_SIZE 114 + +/*! +* Following define start address of mcu_2_app script +*/ +#define mcu_2_app_ADDR 7110 +/*! +* Following define size of mcu_2_app script +*/ +#define mcu_2_app_SIZE 127 + +/*! +* Following define start address of mcu_2_ata script +*/ +#define mcu_2_ata_ADDR 7237 +/*! +* Following define size of mcu_2_ata script +*/ +#define mcu_2_ata_SIZE 87 + +/*! +* Following define start address of mcu_2_firi script +*/ +#define mcu_2_firi_ADDR 7324 +/*! +* Following define size of mcu_2_firi script +*/ +#define mcu_2_firi_SIZE 77 + +/*! +* Following define start address of mcu_2_mshc script +*/ +#define mcu_2_mshc_ADDR 7401 +/*! +* Following define size of mcu_2_mshc script +*/ +#define mcu_2_mshc_SIZE 48 + +/*! +* Following define start address of mcu_2_shp script +*/ +#define mcu_2_shp_ADDR 7449 +/*! +* Following define size of mcu_2_shp script +*/ +#define mcu_2_shp_SIZE 123 + +/*! +* Following define start address of mshc_2_mcu script +*/ +#define mshc_2_mcu_ADDR 7572 +/*! +* Following define size of mshc_2_mcu script +*/ +#define mshc_2_mcu_SIZE 60 + +/*! +* Following define start address of shp_2_mcu script +*/ +#define shp_2_mcu_ADDR 7632 +/*! +* Following define size of shp_2_mcu script +*/ +#define shp_2_mcu_SIZE 101 + +/*! +* Following define start address of uart_2_mcu script +*/ +#define uart_2_mcu_ADDR 7733 +/*! +* Following define size of uart_2_mcu script +*/ +#define uart_2_mcu_SIZE 105 + +/*! +* Following define start address of uartsh_2_mcu script +*/ +#define uartsh_2_mcu_ADDR 7838 +/*! +* Following define size of uartsh_2_mcu script +*/ +#define uartsh_2_mcu_SIZE 98 + +/*! +* Following define the start address of sdma ram +*/ + +#define RAM_CODE_START_ADDR 6144 +/*! +* Following define the size of sdma ram +*/ +#define RAM_CODE_SIZE 1792 + +/*! +* This function returns buffer that holds the image of SDMA RAM. +* This is required to start on a 4-byte aligned boundary on some platforms +* for SDMA to work properly. +* +* @return pointer to buffer that holds the image of SDMA RAM +*/ + +__attribute__ ((__aligned__(4))) +#ifndef CONFIG_XIP_KERNEL +const +#endif +static short sdma_code[] = { + 0xc0ec, 0x7d59, 0x0970, 0x0111, 0x5111, 0x5ad1, 0x5bd9, 0xc0fe, + 0x5ce1, 0x7d02, 0x0200, 0x9806, 0x08ff, 0x0011, 0x28ff, 0x00bc, + 0x05df, 0x7d4b, 0x06df, 0x7d2f, 0x6dc5, 0x6ed5, 0x5ef1, 0x0288, + 0xd81a, 0x9854, 0x0b04, 0x00d3, 0x7d20, 0x06a5, 0x3e03, 0x3d03, + 0x03a5, 0x3b03, 0x008b, 0x058b, 0x7802, 0x63d8, 0x0000, 0x7e72, + 0x63ff, 0x7e70, 0x02a5, 0x008a, 0x4e00, 0x7d01, 0x983d, 0x6dcf, + 0x6edf, 0x0015, 0x0015, 0x7802, 0x63d8, 0x0000, 0x7e63, 0x63ff, + 0x7e61, 0x3a03, 0x008a, 0x6dcd, 0x6edd, 0x7801, 0x63d8, 0x7e5a, + 0x63ff, 0x7e58, 0x0006, 0x6dc5, 0x6e07, 0x5ef1, 0x0288, 0xd8f7, + 0x7e02, 0x7f04, 0x9854, 0x0007, 0x68cc, 0x6b28, 0x54e1, 0x0089, + 0xdb13, 0x0188, 0x5ce1, 0x9854, 0x52d1, 0x53d9, 0x54e1, 0xc10d, + 0x7dad, 0x0200, 0x9800, 0x0200, 0x9800, 0x06df, 0x7d06, 0x6d23, + 0x6ed5, 0x5ef1, 0x0288, 0xd8cd, 0x9854, 0x5ef1, 0x6e07, 0x6d03, + 0x0b04, 0x00d3, 0x7d59, 0x06a5, 0x3e03, 0x3d03, 0x4d00, 0x7d09, + 0x03a5, 0x00a3, 0x0588, 0x008b, 0xd8c9, 0x7ed8, 0x620c, 0x7ed6, + 0x008d, 0x4e00, 0x7c25, 0x0a20, 0x00da, 0x7c22, 0x6503, 0x3d1f, + 0x02a5, 0x00a2, 0x0215, 0x0215, 0x6a18, 0x6a28, 0x7fc7, 0x0a20, + 0x0b08, 0x00da, 0x7c06, 0x6b18, 0x6b28, 0x7fc0, 0x0000, 0x2020, + 0x9889, 0x0688, 0x0015, 0x0015, 0x6818, 0x6828, 0x7fb7, 0x98c2, + 0x0007, 0x6a0c, 0x54e1, 0x0089, 0xdb0f, 0x0188, 0x5ce1, 0x9854, + 0x0b04, 0x00d3, 0x7d21, 0x0389, 0x1b12, 0x048b, 0x0688, 0x0015, + 0x0015, 0x0588, 0x038c, 0x0a08, 0x05da, 0x008d, 0x7c01, 0x008a, + 0x05a0, 0x7803, 0x620b, 0x5a03, 0x1b01, 0x7e98, 0x008b, 0x00a4, + 0x038c, 0x7803, 0x5203, 0x6a0b, 0x1b01, 0x6a28, 0x7f8f, 0x0000, + 0x4d00, 0x7ce8, 0x008e, 0x3803, 0xd8c9, 0x7e88, 0x620c, 0x7e86, + 0x9854, 0x7802, 0x6209, 0x6a29, 0x0006, 0x3e03, 0x4e00, 0x7d11, + 0x0b04, 0x03a6, 0x02db, 0x7d01, 0x038a, 0x02a3, 0x048a, 0x008b, + 0x7802, 0x6329, 0x6bc8, 0x7ebc, 0x63c8, 0x7ebc, 0x008c, 0x4800, + 0x7d15, 0x0488, 0x0015, 0x0015, 0x6edf, 0x7803, 0x632b, 0x6bc8, + 0x0000, 0x7eae, 0x63c8, 0x7eae, 0x008c, 0x3803, 0x6edd, 0x7803, + 0x6329, 0x6bc8, 0x0000, 0x7ea4, 0x63c8, 0x7ea4, 0x0006, 0x3d03, + 0x4d00, 0x7d0e, 0x0b04, 0x03a5, 0x02db, 0x7d01, 0x038a, 0x02a3, + 0x048a, 0x008b, 0x7802, 0x63c8, 0x6b09, 0x7e1e, 0x7f1e, 0x008c, + 0x0488, 0x0015, 0x0015, 0x6dcf, 0x0288, 0x008a, 0x0d08, 0x02dd, + 0x7c01, 0x008d, 0x7802, 0x63c8, 0x6b0b, 0x7e0e, 0x6b28, 0x7f0d, + 0x0000, 0x02dd, 0x7c02, 0x2208, 0x990d, 0x008c, 0x3803, 0x65c0, + 0x6dc5, 0x7802, 0x63c8, 0x6b09, 0x6b28, 0x0006, 0x0870, 0x0011, + 0x5010, 0xc0ec, 0x7d5e, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, + 0x7d02, 0x0200, 0x992c, 0x6ec3, 0x6d07, 0x5df0, 0x0dff, 0x0511, + 0x1dff, 0x05bc, 0x4d00, 0x7d44, 0x0b70, 0x0311, 0x522b, 0x5313, + 0x02b9, 0x4a00, 0x7c04, 0x6a28, 0x7f3a, 0x0400, 0x993c, 0x008f, + 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210, + 0x4a00, 0x7d1c, 0x4a02, 0x7d20, 0x4a01, 0x7d23, 0x0b70, 0x0311, + 0x53eb, 0x62c8, 0x7e24, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6a09, + 0x7f1e, 0x0212, 0x6a09, 0x7f1b, 0x0212, 0x6a09, 0x7f18, 0x2003, + 0x4800, 0x7cef, 0x0b70, 0x0311, 0x5313, 0x997d, 0x0015, 0x0015, + 0x7802, 0x62c8, 0x6a0b, 0x997c, 0x0015, 0x7802, 0x62c8, 0x6a0a, + 0x997c, 0x7802, 0x62c8, 0x6a09, 0x7c02, 0x0000, 0x993a, 0xdb13, + 0x6a28, 0x7ffd, 0x008b, 0x52c3, 0x53cb, 0xc10d, 0x7da5, 0x0200, + 0x992c, 0x0200, 0x9929, 0xc19d, 0xc0ec, 0x7d69, 0x0c70, 0x0411, + 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe, 0x56fa, 0x7d02, + 0x0200, 0x9994, 0x6d07, 0x5bca, 0x5cd2, 0x0bff, 0x0311, 0x1bff, + 0x04bb, 0x0415, 0x53da, 0x4c00, 0x7d47, 0x0a70, 0x0211, 0x552a, + 0x5212, 0x008d, 0x00bb, 0x4800, 0x7c07, 0x05b9, 0x4d00, 0x7c13, + 0x6928, 0x7f2d, 0x0400, 0x99a5, 0x008f, 0x0015, 0x04d8, 0x7d01, + 0x008c, 0x04a0, 0x0015, 0x7802, 0x55c6, 0x6d0b, 0x7e29, 0x6d28, + 0x7f1e, 0x0000, 0x99a3, 0x1e20, 0x5506, 0x2620, 0x008d, 0x0560, + 0x7c08, 0x065f, 0x55c6, 0x063f, 0x7e1b, 0x6d0a, 0x7f10, 0x4c00, + 0x7d1b, 0x04d8, 0x7d02, 0x008c, 0x0020, 0x04a0, 0x0015, 0x7802, + 0x55c6, 0x6d0b, 0x7e0d, 0x6d28, 0x7f02, 0x0000, 0x99ec, 0x0007, + 0x680c, 0x6d0c, 0x6507, 0x6d07, 0x6d2b, 0x6d28, 0x0007, 0x680c, + 0x0007, 0x54d2, 0x0454, 0x99ef, 0x6928, 0x7ff1, 0x54d2, 0x008a, + 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7d9f, 0x0200, 0x9994, 0x0200, + 0x998c, 0xc0ec, 0x7d72, 0x0800, 0x0970, 0x0111, 0x5111, 0x5ac1, + 0x5bc9, 0x028e, 0xc0fe, 0x068a, 0x7c6a, 0x5dd9, 0x5ce1, 0x0bff, + 0x0311, 0x1bff, 0x03bc, 0x5bd1, 0x1a5c, 0x6ac3, 0x63c8, 0x0363, + 0x7c05, 0x036f, 0x7d27, 0x0374, 0x7c7a, 0x9a71, 0xdb04, 0x3c06, + 0x4c00, 0x7df7, 0x028f, 0x1a04, 0x6a23, 0x620b, 0x6f23, 0x301f, + 0x00aa, 0x0462, 0x7c04, 0x4a00, 0x7d0b, 0x2001, 0x9a30, 0x048a, + 0x620b, 0x2201, 0x1c01, 0x1801, 0x02dc, 0x7d02, 0x301f, 0x00aa, + 0x048f, 0x1c04, 0x6c07, 0x0488, 0x3c1f, 0x6c2b, 0x0045, 0x028e, + 0x1a5c, 0x9a11, 0x058f, 0x1d0c, 0x6d23, 0x650b, 0x007d, 0x7c01, + 0x1d08, 0x007c, 0x7c01, 0x1d04, 0x6d23, 0x650b, 0x0488, 0x3c1f, + 0x0417, 0x0417, 0x0417, 0x0417, 0x059c, 0x6d23, 0x028e, 0x1a34, + 0x6ad7, 0x0488, 0x0804, 0x7802, 0x650b, 0x6dc8, 0x008c, 0x1a28, + 0x6ad7, 0x63c8, 0x034c, 0x6bc8, 0x54d1, 0x4c00, 0x7d06, 0x0065, + 0x7c02, 0x0101, 0x0025, 0x0400, 0x9a0d, 0x52c1, 0x53c9, 0x54e1, + 0x0453, 0xc10d, 0x7d95, 0x0200, 0x9a00, 0x0200, 0x99f9, 0x0200, + 0x9a00, 0x55d9, 0x6d07, 0x54d1, 0x058a, 0x2508, 0x6dc7, 0x0373, + 0x7c03, 0x65c8, 0x6d0b, 0x2408, 0x0372, 0x7c04, 0x65c8, 0x6d0b, + 0x2408, 0x9a86, 0x6cce, 0x65c8, 0x6d0a, 0x2404, 0x6d28, 0x6507, + 0x5dd9, 0x5cd1, 0x6ad7, 0x6ae3, 0x63c8, 0x0334, 0x6bc8, 0x0370, + 0x7ca9, 0x0c60, 0x0411, 0x04bb, 0x4c00, 0x7da4, 0x0410, 0x1c30, + 0x0410, 0x04bb, 0x046d, 0x7d0a, 0x047d, 0x7c03, 0x047c, 0x7c01, + 0x9a3a, 0x003b, 0x003a, 0x0039, 0x0058, 0x9ab5, 0x047d, 0x7d03, + 0x047c, 0x7d01, 0x9a3a, 0x005b, 0xdaf9, 0x1d18, 0x6d23, 0x650b, + 0x0510, 0x003a, 0x0039, 0x0038, 0x00ad, 0xdb04, 0x0c30, 0x0410, + 0x04bb, 0x003c, 0x003d, 0x00ac, 0xdaf9, 0x007b, 0x7c04, 0x003d, + 0x003c, 0x1d0c, 0x9ad6, 0x048f, 0x1c14, 0x6c23, 0x640b, 0x4401, + 0x7d04, 0x005d, 0x005c, 0x1d0c, 0x9ad6, 0x0310, 0x3b30, 0x4b30, + 0x7d01, 0x1b10, 0x0310, 0x003d, 0x003c, 0x00ab, 0x6ad7, 0x63c8, + 0x6d23, 0x650b, 0x0560, 0x7d03, 0x005e, 0xdaed, 0x9a3a, 0x003e, + 0x0c80, 0x0410, 0x0394, 0xdaed, 0x640b, 0x037f, 0x7d02, 0x1a14, + 0x9aea, 0x1a0c, 0x6ad7, 0x6cc8, 0x9a3a, 0x0c7f, 0x0410, 0x03b4, + 0x04b8, 0x03ac, 0x640b, 0x6bc8, 0x028e, 0x1a04, 0x6ad7, 0x6cc8, + 0x0006, 0x058f, 0x1d08, 0x6d23, 0x650b, 0x007d, 0x7c01, 0x1d38, + 0x007c, 0x7c01, 0x1d1c, 0x0006, 0x048b, 0x042c, 0x0454, 0x042b, + 0x6ad7, 0x6cc8, 0x0006, 0x0007, 0x684c, 0x6144, 0x9b1c, 0x0007, + 0x68cc, 0x61d0, 0x9b1c, 0x0007, 0x680c, 0x680c, 0x6107, 0x6907, + 0x692b, 0x6928, 0x0007, 0x680c, 0x0d70, 0x0511, 0x5515, 0x55f5, + 0x01a5, 0x0dff, 0x0512, 0x1dff, 0x0512, 0x04bd, 0x0499, 0x0454, + 0x0006, 0x08ff, 0x0011, 0x28ff, 0x0006, 0x038c, 0x0eff, 0x0611, + 0x2eff, 0x03b6, 0x0006, 0x53d6, 0x0398, 0x5bd6, 0x53ee, 0x0398, + 0x5bee, 0x0006, 0x52de, 0x53e6, 0x54ee, 0x0498, 0x0454, 0x0006, + 0x50f6, 0x52c6, 0x53ce, 0x54d6, 0x0498, 0x0454, 0x0006, 0x6207, + 0x0b70, 0x0311, 0x5013, 0x55f0, 0x02a5, 0x0bff, 0x0312, 0x1bff, + 0x0312, 0x04bb, 0x049a, 0x0006, 0x1e10, 0x0870, 0x0011, 0x5010, + 0xc0ec, 0x7d39, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, + 0x0200, 0x9b5b, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d17, 0x6ec3, 0x62c8, 0x7e28, 0x0264, 0x7d08, 0x0b70, + 0x0311, 0x522b, 0x02b9, 0x4a00, 0x7c18, 0x0400, 0x9b6a, 0x0212, + 0x3aff, 0x008a, 0x05d8, 0x7d01, 0x008d, 0x0a10, 0x6ed3, 0x6ac8, + 0xdba5, 0x6a28, 0x7f17, 0x0b70, 0x0311, 0x5013, 0xdbbd, 0x52c0, + 0x53c8, 0xc10d, 0x7dd0, 0x0200, 0x9b5b, 0x008f, 0x00d5, 0x7d01, + 0x008d, 0xdba5, 0x9b68, 0x0200, 0x9b58, 0x0007, 0x68cc, 0x6a28, + 0x7f01, 0x9ba3, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07, 0x6a2b, + 0x6a28, 0x0007, 0x680c, 0x0454, 0x9b81, 0x05a0, 0x1e08, 0x6ec3, + 0x0388, 0x3b03, 0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, 0x7ee5, + 0x6a28, 0x7fe8, 0x0000, 0x6ec1, 0x008b, 0x7802, 0x62c8, 0x6a09, + 0x7edc, 0x6a28, 0x7fdf, 0x2608, 0x0006, 0x55f0, 0x6207, 0x02a5, + 0x0dff, 0x0511, 0x1dff, 0x04b5, 0x049a, 0x0006, 0x0870, 0x0011, + 0x5010, 0xc0ec, 0x7d78, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, + 0x7d02, 0x0200, 0x9bcc, 0x6d03, 0x6ed3, 0x0dff, 0x0511, 0x1dff, + 0x05bc, 0x5df8, 0x4d00, 0x7d5e, 0x0b70, 0x0311, 0x522b, 0x5313, + 0x02b9, 0x4a00, 0x7c04, 0x62ff, 0x7e3f, 0x0400, 0x9bdc, 0x008f, + 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5ddb, 0x0d03, 0x0512, 0x05bc, + 0x0510, 0x5dd3, 0x4d00, 0x7d27, 0x4d02, 0x7d20, 0x4d01, 0x7d1a, + 0x0b70, 0x0311, 0x53eb, 0x0360, 0x7d05, 0x6509, 0x7e25, 0x620a, + 0x7e23, 0x9c06, 0x620a, 0x7e20, 0x6509, 0x7e1e, 0x0512, 0x0512, + 0x02ad, 0x6ac8, 0x7f19, 0x2003, 0x4800, 0x7ced, 0x0b70, 0x0311, + 0x5313, 0x9c21, 0x7802, 0x6209, 0x6ac8, 0x9c20, 0x0015, 0x7802, + 0x620a, 0x6ac8, 0x9c20, 0x0015, 0x0015, 0x7802, 0x620b, 0x6ac8, + 0x7c03, 0x0000, 0x55db, 0x9bda, 0x0007, 0x68cc, 0x680c, 0x55d3, + 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9c2f, 0x0017, 0x0017, 0x55db, + 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, 0x04b8, + 0x04ad, 0x0454, 0x62ff, 0x7ee8, 0x008b, 0x52c0, 0x53c8, 0xc10d, + 0x7d8b, 0x0200, 0x9bcc, 0x0200, 0x9bc9, 0xc19d, 0xc0ec, 0x7d52, + 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe, + 0x56fa, 0x7d02, 0x0200, 0x9c4e, 0x6d03, 0x5bca, 0x5cd2, 0x0bff, + 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da, 0x0a70, 0x0211, 0x4c00, + 0x7d28, 0x552a, 0x05bb, 0x4d00, 0x7c02, 0x0400, 0x9c61, 0x4c01, + 0x7d0f, 0x008f, 0x0015, 0x04d8, 0x7d01, 0x008c, 0x0020, 0x04a0, + 0x0015, 0x7802, 0x650b, 0x5d06, 0x0000, 0x7e0c, 0x7f0d, 0x9c5f, + 0x650a, 0x7e08, 0x008d, 0x0011, 0x0010, 0x05a8, 0x065f, 0x5d06, + 0x063f, 0x7f02, 0x0007, 0x680c, 0x0007, 0x5012, 0x54d0, 0x0454, + 0x9c8b, 0x5012, 0x54d0, 0x0473, 0x7c06, 0x552a, 0x05b9, 0x4d00, + 0x7c02, 0x0400, 0x9c8d, 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7db6, + 0x0200, 0x9c4e, 0x0200, 0x9c46, 0x0870, 0x0011, 0x5010, 0xc0ec, + 0x7d46, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x9ca2, 0x0b70, 0x0311, 0x6ed3, 0x6d03, 0x0dff, 0x0511, 0x1dff, + 0x05bc, 0x4d00, 0x7d2b, 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x62c8, + 0x7e1f, 0x0400, 0x9cb3, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, + 0x0060, 0x7c05, 0x6edd, 0x6209, 0x7e16, 0x6ac8, 0x7f11, 0x0015, + 0x0060, 0x7c05, 0x6ede, 0x620a, 0x7e0e, 0x6ac8, 0x7f09, 0x6edf, + 0x0015, 0x7802, 0x620b, 0x6ac8, 0x0000, 0x7e05, 0x7f01, 0x9cb1, + 0x0007, 0x68cc, 0x9cdd, 0x0007, 0x6a0c, 0x0454, 0x62c8, 0x7ef8, + 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7dbd, 0x0200, 0x9ca2, 0x0200, + 0x9c9f, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d29, 0x5010, 0x5ac0, + 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9cf0, 0x0870, 0x0011, + 0x6d03, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d12, 0x5228, + 0x02b9, 0x4a00, 0x7c02, 0x0400, 0x9cff, 0x620b, 0x7e06, 0x5a06, + 0x7f06, 0x0000, 0x2504, 0x7d05, 0x9cff, 0x0007, 0x680c, 0x0007, + 0x0454, 0x5010, 0x52c0, 0xc10d, 0x7ddb, 0x0200, 0x9cf0, 0x0200, + 0x9cec, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d74, 0x5010, 0x5ac0, + 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9d20, 0x6d03, + 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd0, 0x0dff, 0x0511, 0x1dff, + 0x05bc, 0x5df8, 0x4d00, 0x7d57, 0x0a70, 0x0211, 0x532a, 0x5212, + 0x03b9, 0x4b00, 0x7c02, 0x0400, 0x9d34, 0x008f, 0x05d8, 0x7d01, + 0x008d, 0x05a0, 0x5dda, 0x55d2, 0x4d00, 0x7d27, 0x4d02, 0x7d20, + 0x4d01, 0x7d1a, 0x0a70, 0x0211, 0x52ea, 0x0260, 0x7d05, 0x6509, + 0x7e25, 0x630a, 0x7e23, 0x9d58, 0x630a, 0x7e20, 0x6509, 0x7e1e, + 0x0512, 0x0512, 0x03ad, 0x5b06, 0x7f19, 0x2003, 0x4800, 0x7ced, + 0x0a70, 0x0211, 0x5212, 0x9d73, 0x7802, 0x6309, 0x5b06, 0x9d72, + 0x0015, 0x7802, 0x630a, 0x5b06, 0x9d72, 0x0015, 0x0015, 0x7802, + 0x630b, 0x5b06, 0x7c03, 0x55da, 0x0000, 0x9d32, 0x0007, 0x680c, + 0x55d2, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9d80, 0x0017, 0x0017, + 0x55da, 0x009d, 0x55fa, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, + 0x04b8, 0x04ad, 0x0454, 0x008a, 0x52c0, 0x53c8, 0xc10d, 0x7d90, + 0x0200, 0x9d20, 0x0200, 0x9d1c, 0xc19d, 0x0870, 0x0011, 0xc0ec, + 0x7d35, 0x5010, 0x5ac0, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x9d9b, 0x0870, 0x0011, 0x6d07, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d1c, 0x5228, 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f0b, + 0x0400, 0x9daa, 0x5206, 0x7e10, 0x6a0b, 0x6928, 0x7f04, 0x0000, + 0x2504, 0x7d0c, 0x9daa, 0x0007, 0x680c, 0x680c, 0x6207, 0x6a07, + 0x6a2b, 0x6a28, 0x0007, 0x680c, 0x0007, 0x0454, 0x6928, 0x7ff3, + 0x5010, 0x52c0, 0xc10d, 0x7dcf, 0x0200, 0x9d9b, 0x0200, 0x9d97, + 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d5e, 0x5010, 0x5ac0, 0x5bc8, + 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9dd7, 0x6d07, 0x5df0, + 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d44, 0x0a70, 0x0211, + 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c04, 0x6a28, 0x7f3a, 0x0400, + 0x9de6, 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x0b03, 0x0312, + 0x03bc, 0x0310, 0x4b00, 0x7d1c, 0x4b02, 0x7d20, 0x4b01, 0x7d23, + 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e24, 0x0260, 0x7d02, 0x0310, + 0x0312, 0x6b09, 0x7f1e, 0x0312, 0x6b09, 0x7f1b, 0x0312, 0x6b09, + 0x7f18, 0x2003, 0x4800, 0x7cef, 0x0a70, 0x0211, 0x5212, 0x9e27, + 0x0015, 0x0015, 0x7802, 0x5306, 0x6b0b, 0x9e26, 0x0015, 0x7802, + 0x5306, 0x6b0a, 0x9e26, 0x7802, 0x5306, 0x6b09, 0x7c02, 0x0000, + 0x9de4, 0xdb13, 0x6928, 0x7ffd, 0x008a, 0x52c0, 0x53c8, 0xc10d, + 0x7da6, 0x0200, 0x9dd7, 0x0200, 0x9dd3, 0x0870, 0x0011, 0x5010, + 0xc0ec, 0x7d5b, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, + 0x0200, 0x9e3b, 0x0b70, 0x0311, 0x6ec3, 0x6d07, 0x5df0, 0x0dff, + 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d3d, 0x522b, 0x02b9, 0x4a00, + 0x7c04, 0x6a28, 0x7f33, 0x0400, 0x9e4d, 0x028e, 0x1a94, 0x6ac3, + 0x62c8, 0x0269, 0x7d1b, 0x1e94, 0x6ec3, 0x6ed3, 0x62c8, 0x0248, + 0x6ac8, 0x2694, 0x6ec3, 0x62c8, 0x026e, 0x7d31, 0x6a09, 0x7f1e, + 0x2501, 0x4d00, 0x7d1f, 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3, + 0x0260, 0x7df1, 0x6a28, 0x7f12, 0xdb47, 0x9e8c, 0x6ee3, 0x008f, + 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d17, + 0x6a09, 0x7f04, 0x2001, 0x7cf9, 0x0000, 0x9e4b, 0x0289, 0xdb13, + 0x018a, 0x9e9b, 0x6a28, 0x7ffa, 0x0b70, 0x0311, 0x5013, 0x52c0, + 0x53c8, 0xc10d, 0x7da8, 0x0200, 0x9e3b, 0x0200, 0x9e38, 0x6a28, + 0x7fed, 0xdb47, 0x9e9b, 0x0458, 0x0454, 0x9e8c, 0xc19d, 0x0870, + 0x0011, 0xc0ec, 0x7d54, 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, + 0x56f8, 0x7d02, 0x0200, 0x9ea5, 0x0b70, 0x0311, 0x6d07, 0x5df0, + 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d36, 0x522b, 0x02b9, + 0x4a00, 0x7c04, 0x6928, 0x7f2c, 0x0400, 0x9eb6, 0x028e, 0x1a94, + 0x5202, 0x0269, 0x7d16, 0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694, + 0x5206, 0x026e, 0x7d2e, 0x6a09, 0x7f1b, 0x2501, 0x4d00, 0x7d1c, + 0x028e, 0x1a98, 0x5202, 0x0260, 0x7df3, 0x6a28, 0x7f11, 0xdb47, + 0x9eee, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, + 0x026e, 0x7d17, 0x6a09, 0x7f04, 0x2001, 0x7cf9, 0x0000, 0x9eb4, + 0x0289, 0xdb13, 0x018a, 0x9efd, 0x6928, 0x7ffa, 0x0b70, 0x0311, + 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7db0, 0x0200, 0x9ea5, 0x0200, + 0x9ea1, 0x6a28, 0x7fed, 0xdb47, 0x9efd, 0x0458, 0x0454, 0x9eee, + 0x9eee +}; +#endif diff --git a/arch/arm/mach-mx3/sdma_script_code_pass2.h b/arch/arm/mach-mx3/sdma_script_code_pass2.h new file mode 100644 index 000000000000..85de716c45f9 --- /dev/null +++ b/arch/arm/mach-mx3/sdma_script_code_pass2.h @@ -0,0 +1,434 @@ +/* + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! + * @file sdma_script_code.h + * @brief This file contains functions of SDMA scripts code initialization + * + * The file was generated automatically. Based on sdma scripts library. + * + * @ingroup SDMA + */ +/******************************************************************************* + + SDMA RELEASE LABEL: "SS15_MX31" + +*******************************************************************************/ + +#ifndef __SDMA_SCRIPT_CODE_PASS2_H__ +#define __SDMA_SCRIPT_CODE_PASS2_H__ + +/*! +* SDMA ROM scripts start addresses and sizes +*/ + +#define start_ADDR_2 0 +#define start_SIZE_2 20 + +#define core_ADDR_2 80 +#define core_SIZE_2 152 + +#define common_ADDR_2 232 +#define common_SIZE_2 191 + +#define ap_2_ap_ADDR_2 423 +#define ap_2_ap_SIZE_2 294 + +#define bp_2_bp_ADDR_2 717 +#define bp_2_bp_SIZE_2 112 + +#define ap_2_bp_ADDR_2 829 +#define ap_2_bp_SIZE_2 200 + +#define bp_2_ap_ADDR_2 1029 +#define bp_2_ap_SIZE_2 223 + +#define app_2_mcu_ADDR_2 1252 +#define app_2_mcu_SIZE_2 101 + +#define mcu_2_app_ADDR_2 1353 +#define mcu_2_app_SIZE_2 127 + +#define uart_2_mcu_ADDR_2 1480 +#define uart_2_mcu_SIZE_2 105 + +#define uartsh_2_mcu_ADDR_2 1585 +#define uartsh_2_mcu_SIZE_2 98 + +#define mcu_2_shp_ADDR_2 1683 +#define mcu_2_shp_SIZE_2 123 + +#define shp_2_mcu_ADDR_2 1806 +#define shp_2_mcu_SIZE_2 101 + +#define error_ADDR_2 1907 +#define error_SIZE_2 73 + +#define test_ADDR_2 1980 +#define test_SIZE_2 63 + +#define signature_ADDR_2 1023 +#define signature_SIZE_2 1 + +/*! +* SDMA RAM scripts start addresses and sizes +*/ + +#define ap_2_ap_fixed_addr_ADDR_2 6144 +#define ap_2_ap_fixed_addr_SIZE_2 68 + +#define app_2_mcu_patched_ADDR_2 6212 +#define app_2_mcu_patched_SIZE_2 104 + +#undef app_2_mcu_ADDR_2 +#undef app_2_mcu_SIZE_2 + +/*mapping the app_2_mcu start address to the patched(RAM)script start address*/ +#define app_2_mcu_ADDR_2 app_2_mcu_patched_ADDR_2 +#define app_2_mcu_SIZE_2 app_2_mcu_patched_SIZE_2 + +#define app_2_per_ADDR_2 6316 +#define app_2_per_SIZE_2 105 + +#define ata_2_mcu_ADDR_2 6421 +#define ata_2_mcu_SIZE_2 110 + +#define firi_2_mcu_ADDR_2 6531 +#define firi_2_mcu_SIZE_2 114 + +#define loop_DMAs_fixed_addr_ADDR_2 6645 +#define loop_DMAs_fixed_addr_SIZE_2 90 + +#define mcu_2_app_patched_ADDR_2 6735 +#define mcu_2_app_patched_SIZE_2 129 + +#undef mcu_2_app_ADDR_2 +#undef mcu_2_app_SIZE_2 + +/*mapping the mcu_2_app start address to the patched(RAM)script start address*/ +#define mcu_2_app_ADDR_2 mcu_2_app_patched_ADDR_2 +#define mcu_2_app_SIZE_2 mcu_2_app_patched_SIZE_2 + +#define mcu_2_ata_ADDR_2 6864 +#define mcu_2_ata_SIZE_2 87 + +#define mcu_2_firi_ADDR_2 6951 +#define mcu_2_firi_SIZE_2 77 + +#define mcu_2_mshc_ADDR_2 7028 +#define mcu_2_mshc_SIZE_2 48 + +#define mcu_2_shp_patched_ADDR_2 7076 +#define mcu_2_shp_patched_SIZE_2 125 + +#undef mcu_2_shp_ADDR_2 +#undef mcu_2_shp_SIZE_2 + +/*mapping the mcu_2_shp start address to the patched(RAM)script start address*/ +#define mcu_2_shp_ADDR_2 mcu_2_shp_patched_ADDR_2 +#define mcu_2_shp_SIZE_2 mcu_2_shp_patched_SIZE_2 + +#define mshc_2_mcu_ADDR_2 7201 +#define mshc_2_mcu_SIZE_2 60 + +#define per_2_app_ADDR_2 7261 +#define per_2_app_SIZE_2 131 + +#define per_2_shp_ADDR_2 7392 +#define per_2_shp_SIZE_2 131 + +#define shp_2_mcu_patched_ADDR_2 7523 +#define shp_2_mcu_patched_SIZE_2 104 + +#undef shp_2_mcu_ADDR_2 +#undef shp_2_mcu_SIZE_2 + +/*mapping the shp_2_mcu start address to the patched(RAM)script start address*/ +#define shp_2_mcu_ADDR_2 shp_2_mcu_patched_ADDR_2 +#define shp_2_mcu_SIZE_2 shp_2_mcu_patched_SIZE_2 + +#define shp_2_per_ADDR_2 7627 +#define shp_2_per_SIZE_2 109 + +#define uart_2_mcu_patched_ADDR_2 7736 +#define uart_2_mcu_patched_SIZE_2 106 + +#undef uart_2_mcu_ADDR_2 +#undef uart_2_mcu_SIZE_2 + +/*mapping the uart_2_mcu start address to the patched(RAM)script start address*/ +#define uart_2_mcu_ADDR_2 uart_2_mcu_patched_ADDR_2 +#define uart_2_mcu_SIZE_2 uart_2_mcu_patched_SIZE_2 + +#define uartsh_2_mcu_patched_ADDR_2 7842 +#define uartsh_2_mcu_patched_SIZE_2 99 + +#undef uartsh_2_mcu_ADDR_2 +#undef uartsh_2_mcu_SIZE_2 + +/* + * mapping the uartsh_2_mcu start address to the patched(RAM)script + * start address + */ +#define uartsh_2_mcu_ADDR_2 uartsh_2_mcu_patched_ADDR_2 +#define uartsh_2_mcu_SIZE_2 uartsh_2_mcu_patched_SIZE_2 + +/*! +* SDMA RAM image start address and size +*/ + +#define RAM_CODE_START_ADDR_2 6144 +#define RAM_CODE_SIZE_2 1797 + +/*! +* Buffer that holds the SDMA RAM image +*/ + +__attribute__ ((__aligned__(4))) +#ifndef CONFIG_XIP_KERNEL +const +#endif +static const short sdma_code_2[] = { + 0x0970, 0x0111, 0x5111, 0x5ef9, 0xc0ec, 0x7d23, 0x5ad1, 0x5bd9, + 0xc0fe, 0x7c1f, 0x5ce1, 0x5de9, 0x5ef1, 0x08ff, 0x0011, 0x28ff, + 0x00bc, 0x048e, 0x56f9, 0x0660, 0x7d05, 0x0661, 0x7c2b, 0x6c07, + 0x6d13, 0x9821, 0x0661, 0x7d26, 0x6c17, 0x6d03, 0x028d, 0x058c, + 0x048a, 0xd9f5, 0x7e08, 0x7f07, 0x54e1, 0x52d1, 0x53d9, 0xc10d, + 0x7dde, 0x0200, 0x9804, 0x0660, 0x7d03, 0x6007, 0x52f1, 0x9832, + 0x6003, 0x52e9, 0x00a2, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07, + 0x6a2b, 0x6a28, 0x0007, 0x6a0c, 0x54e1, 0xc795, 0x048b, 0x0498, + 0x0454, 0x9825, 0x0800, 0x983c, 0x0870, 0x0011, 0x5010, 0xc0ec, + 0x7d61, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x984a, 0x6ec3, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d45, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9, 0x4a00, + 0x7c04, 0x6a28, 0x7f3b, 0x0400, 0x985a, 0x008f, 0x00d5, 0x7d01, + 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210, 0x4a00, 0x7d1c, + 0x4a02, 0x7d20, 0x4a01, 0x7d23, 0x0b70, 0x0311, 0x53eb, 0x62c8, + 0x7e25, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6a09, 0x7f1f, 0x0212, + 0x6a09, 0x7f1c, 0x0212, 0x6a09, 0x7f19, 0x2003, 0x4800, 0x7cef, + 0x0b70, 0x0311, 0x5313, 0x989b, 0x0015, 0x0015, 0x7802, 0x62c8, + 0x6a0b, 0x989a, 0x0015, 0x7802, 0x62c8, 0x6a0a, 0x989a, 0x7802, + 0x62c8, 0x6a09, 0x7c03, 0x6a28, 0x0000, 0x9858, 0xc77b, 0x6a28, + 0x7ffd, 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da2, + 0x0200, 0x984a, 0x0200, 0x9847, 0x0870, 0x0011, 0x5010, 0xc0ec, + 0x7d62, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x98b2, 0x6ec3, 0x6dd7, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d46, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9, 0x4a00, + 0x7c04, 0x62ff, 0x7e3c, 0x0400, 0x98c2, 0x008f, 0x00d5, 0x7d01, + 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210, 0x4a00, 0x7d28, + 0x4a02, 0x7d20, 0x4a01, 0x7d19, 0x6ddd, 0x0b70, 0x0311, 0x53eb, + 0x62c8, 0x7e25, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6ac8, 0x7f1f, + 0x0212, 0x6ac8, 0x7f1c, 0x0212, 0x6ac8, 0x7f19, 0x2003, 0x4800, + 0x7cef, 0x0b70, 0x0311, 0x5313, 0x9905, 0x6ddd, 0x7802, 0x62c8, + 0x6ac8, 0x9904, 0x6dde, 0x0015, 0x7802, 0x62c8, 0x6ac8, 0x9904, + 0x0015, 0x0015, 0x7801, 0x62d8, 0x7c02, 0x0000, 0x98c0, 0xc777, + 0x62ff, 0x7efd, 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, + 0x7da1, 0x0200, 0x98b2, 0x0200, 0x98af, 0xc19d, 0xc0ec, 0x7d69, + 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe, + 0x56fa, 0x7d02, 0x0200, 0x991e, 0x6d07, 0x5bca, 0x5cd2, 0x0bff, + 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da, 0x4c00, 0x7d47, 0x0a70, + 0x0211, 0x552a, 0x5212, 0x008d, 0x00bb, 0x4800, 0x7c07, 0x05b9, + 0x4d00, 0x7c13, 0x6928, 0x7f2d, 0x0400, 0x992f, 0x008f, 0x0015, + 0x04d8, 0x7d01, 0x008c, 0x04a0, 0x0015, 0x7802, 0x55c6, 0x6d0b, + 0x7e29, 0x6d28, 0x7f1e, 0x0000, 0x992d, 0x1e20, 0x5506, 0x2620, + 0x008d, 0x0560, 0x7c08, 0x065f, 0x55c6, 0x063f, 0x7e1b, 0x6d0a, + 0x7f10, 0x4c00, 0x7d1b, 0x04d8, 0x7d02, 0x008c, 0x0020, 0x04a0, + 0x0015, 0x7802, 0x55c6, 0x6d0b, 0x7e0d, 0x6d28, 0x7f02, 0x0000, + 0x9976, 0x0007, 0x680c, 0x6d0c, 0x6507, 0x6d07, 0x6d2b, 0x6d28, + 0x0007, 0x680c, 0x0007, 0x54d2, 0x0454, 0x9979, 0x6928, 0x7ff1, + 0x54d2, 0x008a, 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7d9f, 0x0200, + 0x991e, 0x0200, 0x9916, 0x1e10, 0x0870, 0x0011, 0x5010, 0xc0ec, + 0x7d39, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x998a, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, + 0x7d17, 0x6ec3, 0x62c8, 0x7e28, 0x0264, 0x7d08, 0x0b70, 0x0311, + 0x522b, 0x02b9, 0x4a00, 0x7c18, 0x0400, 0x9999, 0x0212, 0x3aff, + 0x008a, 0x05d8, 0x7d01, 0x008d, 0x0a10, 0x6ed3, 0x6ac8, 0xd9d4, + 0x6a28, 0x7f17, 0x0b70, 0x0311, 0x5013, 0xd9ec, 0x52c0, 0x53c8, + 0xc10d, 0x7dd0, 0x0200, 0x998a, 0x008f, 0x00d5, 0x7d01, 0x008d, + 0xd9d4, 0x9997, 0x0200, 0x9987, 0x0007, 0x68cc, 0x6a28, 0x7f01, + 0x99d2, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07, 0x6a2b, 0x6a28, + 0x0007, 0x680c, 0x0454, 0x99b0, 0x05a0, 0x1e08, 0x6ec3, 0x0388, + 0x3b03, 0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, 0x7ee5, 0x6a28, + 0x7fe8, 0x0000, 0x6ec1, 0x008b, 0x7802, 0x62c8, 0x6a09, 0x7edc, + 0x6a28, 0x7fdf, 0x2608, 0x0006, 0x55f0, 0x6207, 0x02a5, 0x0dff, + 0x0511, 0x1dff, 0x04b5, 0x049a, 0x0006, 0x0388, 0x028d, 0x3a03, + 0x4a00, 0x7c33, 0x028c, 0x3a03, 0x4a00, 0x7d0c, 0x0804, 0x00a2, + 0x00db, 0x7d24, 0x03a0, 0x0498, 0x7802, 0x6209, 0x6a29, 0x7e24, + 0x620c, 0x7e22, 0x0804, 0x03d0, 0x7d19, 0x0820, 0x028c, 0x3a1f, + 0x00a2, 0x03d0, 0x7c02, 0x008b, 0x3003, 0x03a0, 0x0015, 0x0015, + 0x6818, 0x7e12, 0x6828, 0x7f10, 0x0000, 0x0820, 0x03d8, 0x7df5, + 0x0804, 0x03d0, 0x7d03, 0x008b, 0x3003, 0x9a15, 0x008b, 0x7802, + 0x6209, 0x6a29, 0x7e01, 0x620c, 0x0006, 0x0804, 0x03d0, 0x7df6, + 0x048b, 0x3403, 0x03a4, 0x0415, 0x0415, 0x0d0f, 0x0511, 0x1df0, + 0x0808, 0x04d0, 0x7c01, 0x008c, 0x58c1, 0x04a0, 0x7803, 0x620b, + 0x5a05, 0x1d01, 0x7ee9, 0x50c1, 0x05a0, 0x7803, 0x5205, 0x6a0b, + 0x1d01, 0x6a28, 0x7fe1, 0x0000, 0x4c00, 0x7ce7, 0x9a26, 0x0870, + 0x0011, 0x5010, 0xc0ec, 0x7d7a, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, + 0x56f8, 0x7d02, 0x0200, 0x9a55, 0x6d03, 0x6ed3, 0x0dff, 0x0511, + 0x1dff, 0x05bc, 0x5df8, 0x4d00, 0x7d5e, 0x0b70, 0x0311, 0x522b, + 0x5313, 0x02b9, 0x4a00, 0x7c04, 0x62ff, 0x7e3f, 0x0400, 0x9a65, + 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5ddb, 0x0d03, 0x0512, + 0x05bc, 0x0510, 0x5dd3, 0x4d00, 0x7d27, 0x4d02, 0x7d20, 0x4d01, + 0x7d1a, 0x0b70, 0x0311, 0x53eb, 0x0360, 0x7d05, 0x6509, 0x7e25, + 0x620a, 0x7e23, 0x9a8f, 0x620a, 0x7e20, 0x6509, 0x7e1e, 0x0512, + 0x0512, 0x02ad, 0x6ac8, 0x7f19, 0x2003, 0x4800, 0x7ced, 0x0b70, + 0x0311, 0x5313, 0x9aaa, 0x7802, 0x6209, 0x6ac8, 0x9aa9, 0x0015, + 0x7802, 0x620a, 0x6ac8, 0x9aa9, 0x0015, 0x0015, 0x7802, 0x620b, + 0x6ac8, 0x7c03, 0x0000, 0x55db, 0x9a63, 0x0007, 0x68cc, 0x680c, + 0x55d3, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9ab8, 0x0017, 0x0017, + 0x55db, 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, + 0x04b8, 0x04ad, 0x0454, 0x62ff, 0x7ee8, 0x0870, 0x0011, 0x5010, + 0x52c0, 0x53c8, 0xc10d, 0x7d89, 0x0200, 0x9a55, 0x0200, 0x9a52, + 0xc19d, 0xc0ec, 0x7d52, 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c, + 0x58da, 0x5efa, 0xc0fe, 0x56fa, 0x7d02, 0x0200, 0x9ad9, 0x6d03, + 0x5bca, 0x5cd2, 0x0bff, 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da, + 0x0a70, 0x0211, 0x4c00, 0x7d28, 0x552a, 0x05bb, 0x4d00, 0x7c02, + 0x0400, 0x9aec, 0x4c01, 0x7d0f, 0x008f, 0x0015, 0x04d8, 0x7d01, + 0x008c, 0x0020, 0x04a0, 0x0015, 0x7802, 0x650b, 0x5d06, 0x0000, + 0x7e0c, 0x7f0d, 0x9aea, 0x650a, 0x7e08, 0x008d, 0x0011, 0x0010, + 0x05a8, 0x065f, 0x5d06, 0x063f, 0x7f02, 0x0007, 0x680c, 0x0007, + 0x5012, 0x54d0, 0x0454, 0x9b16, 0x5012, 0x54d0, 0x0473, 0x7c06, + 0x552a, 0x05b9, 0x4d00, 0x7c02, 0x0400, 0x9b18, 0x52c0, 0x53c8, + 0xc10d, 0x0288, 0x7db6, 0x0200, 0x9ad9, 0x0200, 0x9ad1, 0x0870, + 0x0011, 0x5010, 0xc0ec, 0x7d46, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, + 0x56f8, 0x7d02, 0x0200, 0x9b2d, 0x0b70, 0x0311, 0x6ed3, 0x6d03, + 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d2b, 0x522b, 0x02b9, + 0x4a00, 0x7c04, 0x62c8, 0x7e1f, 0x0400, 0x9b3e, 0x008f, 0x00d5, + 0x7d01, 0x008d, 0x05a0, 0x0060, 0x7c05, 0x6edd, 0x6209, 0x7e16, + 0x6ac8, 0x7f11, 0x0015, 0x0060, 0x7c05, 0x6ede, 0x620a, 0x7e0e, + 0x6ac8, 0x7f09, 0x6edf, 0x0015, 0x7802, 0x620b, 0x6ac8, 0x0000, + 0x7e05, 0x7f01, 0x9b3c, 0x0007, 0x68cc, 0x9b68, 0x0007, 0x6a0c, + 0x0454, 0x62c8, 0x7ef8, 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7dbd, + 0x0200, 0x9b2d, 0x0200, 0x9b2a, 0xc19d, 0x0870, 0x0011, 0xc0ec, + 0x7d29, 0x5010, 0x5ac0, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x9b7b, 0x0870, 0x0011, 0x6d03, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d12, 0x5228, 0x02b9, 0x4a00, 0x7c02, 0x0400, 0x9b8a, + 0x620b, 0x7e06, 0x5a06, 0x7f06, 0x0000, 0x2504, 0x7d05, 0x9b8a, + 0x0007, 0x680c, 0x0007, 0x0454, 0x5010, 0x52c0, 0xc10d, 0x7ddb, + 0x0200, 0x9b7b, 0x0200, 0x9b77, 0xc19d, 0x0870, 0x0011, 0xc0ec, + 0x7d76, 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, + 0x0200, 0x9bab, 0x6d03, 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd0, + 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x5df8, 0x4d00, 0x7d57, 0x0a70, + 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c02, 0x0400, 0x9bbf, + 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x5dda, 0x55d2, 0x4d00, + 0x7d27, 0x4d02, 0x7d20, 0x4d01, 0x7d1a, 0x0a70, 0x0211, 0x52ea, + 0x0260, 0x7d05, 0x6509, 0x7e25, 0x630a, 0x7e23, 0x9be3, 0x630a, + 0x7e20, 0x6509, 0x7e1e, 0x0512, 0x0512, 0x03ad, 0x5b06, 0x7f19, + 0x2003, 0x4800, 0x7ced, 0x0a70, 0x0211, 0x5212, 0x9bfe, 0x7802, + 0x6309, 0x5b06, 0x9bfd, 0x0015, 0x7802, 0x630a, 0x5b06, 0x9bfd, + 0x0015, 0x0015, 0x7802, 0x630b, 0x5b06, 0x7c03, 0x55da, 0x0000, + 0x9bbd, 0x0007, 0x680c, 0x55d2, 0x4d00, 0x7d03, 0x4d02, 0x7d02, + 0x9c0b, 0x0017, 0x0017, 0x55da, 0x009d, 0x55fa, 0x05a0, 0x08ff, + 0x0011, 0x18ff, 0x0010, 0x04b8, 0x04ad, 0x0454, 0x0870, 0x0011, + 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7d8e, 0x0200, 0x9bab, 0x0200, + 0x9ba7, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d35, 0x5010, 0x5ac0, + 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9c28, 0x0870, 0x0011, + 0x6d07, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d1c, 0x5228, + 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f0b, 0x0400, 0x9c37, 0x5206, + 0x7e10, 0x6a0b, 0x6928, 0x7f04, 0x0000, 0x2504, 0x7d0c, 0x9c37, + 0x0007, 0x680c, 0x680c, 0x6207, 0x6a07, 0x6a2b, 0x6a28, 0x0007, + 0x680c, 0x0007, 0x0454, 0x6928, 0x7ff3, 0x5010, 0x52c0, 0xc10d, + 0x7dcf, 0x0200, 0x9c28, 0x0200, 0x9c24, 0x0870, 0x0011, 0x5010, + 0xc0ec, 0x7d7c, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, + 0x0200, 0x9c63, 0x6ed3, 0x6dc5, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x5df8, 0x4d00, 0x7d60, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9, + 0x4a00, 0x7c02, 0x0400, 0x9c73, 0x008f, 0x00d5, 0x7d01, 0x008d, + 0x05a0, 0x5ddb, 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd3, 0x4d00, + 0x7d2c, 0x4d02, 0x7d24, 0x4d01, 0x7d1e, 0x59e3, 0x0b70, 0x0311, + 0x53eb, 0x61c8, 0x7e2b, 0x62c8, 0x7e29, 0x65c8, 0x7e27, 0x0360, + 0x7d03, 0x0112, 0x0112, 0x9c9e, 0x0512, 0x0512, 0x0211, 0x02a9, + 0x02ad, 0x6ac8, 0x7f1b, 0x2003, 0x4800, 0x7ceb, 0x0b70, 0x0311, + 0x5313, 0x51e3, 0x9cbb, 0x7802, 0x62c8, 0x6ac8, 0x9cba, 0x6dce, + 0x0015, 0x7802, 0x62c8, 0x6ac8, 0x9cba, 0x6dcf, 0x0015, 0x0015, + 0x7801, 0x62d8, 0x7c03, 0x0000, 0x55db, 0x9c71, 0x0007, 0x68ff, + 0x55d3, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9cc8, 0x0017, 0x0017, + 0x55db, 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, + 0x04b8, 0x04ad, 0x0454, 0x62c8, 0x7ee9, 0x0870, 0x0011, 0x5010, + 0x52c0, 0x53c8, 0xc10d, 0x7d87, 0x0200, 0x9c63, 0x0200, 0x9c60, + 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d7c, 0x5010, 0x5ac0, 0x5bc8, + 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9ce7, 0x6dc5, 0x0d03, + 0x0512, 0x05bc, 0x0510, 0x5dd0, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x5df8, 0x4d00, 0x7d5d, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9, + 0x4b00, 0x7c02, 0x0400, 0x9cfb, 0x008f, 0x05d8, 0x7d01, 0x008d, + 0x05a0, 0x5dda, 0x55d2, 0x4d00, 0x7d2c, 0x4d02, 0x7d24, 0x4d01, + 0x7d1e, 0x59e2, 0x0a70, 0x0211, 0x52ea, 0x61c8, 0x7e2c, 0x63c8, + 0x7e2a, 0x65c8, 0x7e28, 0x0260, 0x7d03, 0x0112, 0x0112, 0x9d22, + 0x0512, 0x0512, 0x0311, 0x03a9, 0x03ad, 0x5b06, 0x7f1c, 0x2003, + 0x4800, 0x7ceb, 0x0a70, 0x0211, 0x5212, 0x51e2, 0x9d40, 0x7802, + 0x63c8, 0x5b06, 0x9d3f, 0x6dce, 0x0015, 0x7802, 0x63c8, 0x5b06, + 0x9d3f, 0x6dcf, 0x0015, 0x0015, 0x7802, 0x63c8, 0x5b06, 0x7c03, + 0x55da, 0x0000, 0x9cf9, 0x0007, 0x68ff, 0x55d2, 0x4d00, 0x7d03, + 0x4d02, 0x7d02, 0x9d4d, 0x0017, 0x0017, 0x55da, 0x009d, 0x55fa, + 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, 0x04b8, 0x04ad, 0x0454, + 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7d88, 0x0200, + 0x9ce7, 0x0200, 0x9ce3, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d61, + 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x9d6a, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, + 0x7d45, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c04, + 0x6a28, 0x7f3b, 0x0400, 0x9d79, 0x008f, 0x05d8, 0x7d01, 0x008d, + 0x05a0, 0x0b03, 0x0312, 0x03bc, 0x0310, 0x4b00, 0x7d1c, 0x4b02, + 0x7d20, 0x4b01, 0x7d23, 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e25, + 0x0260, 0x7d02, 0x0310, 0x0312, 0x6b09, 0x7f1f, 0x0312, 0x6b09, + 0x7f1c, 0x0312, 0x6b09, 0x7f19, 0x2003, 0x4800, 0x7cef, 0x0a70, + 0x0211, 0x5212, 0x9dba, 0x0015, 0x0015, 0x7802, 0x5306, 0x6b0b, + 0x9db9, 0x0015, 0x7802, 0x5306, 0x6b0a, 0x9db9, 0x7802, 0x5306, + 0x6b09, 0x7c03, 0x6b28, 0x0000, 0x9d77, 0xc77b, 0x6928, 0x7ffd, + 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da3, 0x0200, + 0x9d6a, 0x0200, 0x9d66, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d60, + 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, + 0x9dd2, 0x6dd7, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, + 0x7d46, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c02, + 0x0400, 0x9de1, 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x0b03, + 0x0312, 0x03bc, 0x0310, 0x4b00, 0x7d28, 0x4b02, 0x7d20, 0x4b01, + 0x7d19, 0x6ddd, 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e27, 0x0260, + 0x7d02, 0x0310, 0x0312, 0x6bc8, 0x7f21, 0x0312, 0x6bc8, 0x7f1e, + 0x0312, 0x6bc8, 0x7f1b, 0x2003, 0x4800, 0x7cef, 0x0a70, 0x0211, + 0x5212, 0x9e23, 0x6ddd, 0x7802, 0x5306, 0x6bc8, 0x9e22, 0x6dde, + 0x0015, 0x7802, 0x5306, 0x6bc8, 0x9e22, 0x0015, 0x0015, 0x7802, + 0x5306, 0x6bc8, 0x7c03, 0x0000, 0xde32, 0x9ddf, 0xc777, 0x0870, + 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da4, 0x0200, 0x9dd2, + 0x0200, 0x9dce, 0x63ff, 0x0368, 0x7d02, 0x0369, 0x7def, 0x0006, + 0x0870, 0x0011, 0x5010, 0xc0ec, 0x7d5c, 0x5ac0, 0x5bc8, 0x5ef8, + 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9e3e, 0x0b70, 0x0311, 0x6ec3, + 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d3e, + 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x6a28, 0x7f34, 0x0400, 0x9e50, + 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1b, 0x1e94, 0x6ec3, + 0x6ed3, 0x62c8, 0x0248, 0x6ac8, 0x2694, 0x6ec3, 0x62c8, 0x026e, + 0x7d32, 0x6a09, 0x7f1f, 0x2501, 0x4d00, 0x7d20, 0x028e, 0x1a98, + 0x6ac3, 0x62c8, 0x6ec3, 0x0260, 0x7df1, 0x6a28, 0x7f13, 0xc7af, + 0x9e90, 0x6ee3, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, + 0x62c8, 0x026e, 0x7d18, 0x6a09, 0x7f05, 0x2001, 0x7cf9, 0x6a28, + 0x0000, 0x9e4e, 0x0289, 0xc77b, 0x018a, 0x9e9f, 0x6a28, 0x7ffa, + 0x0b70, 0x0311, 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7da7, 0x0200, + 0x9e3e, 0x0200, 0x9e3b, 0x6a28, 0x7fed, 0xc7af, 0x9e9f, 0x0458, + 0x0454, 0x9e90, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d55, 0x5010, + 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9ea9, + 0x0b70, 0x0311, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, + 0x4d00, 0x7d37, 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f2d, + 0x0400, 0x9eba, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d16, 0x1e94, + 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d2f, 0x6a09, + 0x7f1c, 0x2501, 0x4d00, 0x7d1d, 0x028e, 0x1a98, 0x5202, 0x0260, + 0x7df3, 0x6a28, 0x7f12, 0xc7af, 0x9ef3, 0x008f, 0x2001, 0x00d5, + 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d18, 0x6a09, 0x7f05, + 0x2001, 0x7cf9, 0x6a28, 0x0000, 0x9eb8, 0x0289, 0xc77b, 0x018a, + 0x9f02, 0x6928, 0x7ffa, 0x0b70, 0x0311, 0x5013, 0x52c0, 0x53c8, + 0xc10d, 0x7daf, 0x0200, 0x9ea9, 0x0200, 0x9ea5, 0x6a28, 0x7fed, + 0xc7af, 0x9f02, 0x0458, 0x0454, 0x9ef3 +}; +#endif diff --git a/arch/arm/mach-mx3/serial.c b/arch/arm/mach-mx3/serial.c new file mode 100644 index 000000000000..fca1b5b8a38f --- /dev/null +++ b/arch/arm/mach-mx3/serial.c @@ -0,0 +1,267 @@ +/* + * Copyright 2006-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +/*! + * @file mach-mx3/serial.c + * + * @brief This file contains the UART initiliazation. + * + * @ingroup MSL_MX31 + */ +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <mach/hardware.h> +#include <mach/mxc_uart.h> +#include <mach/spba.h> +#include "serial.h" +#include "board-mx31ads.h" +#include "board-mx3_3stack.h" + +#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) + +/*! + * This is an array where each element holds information about a UART port, + * like base address of the UART, interrupt numbers etc. This structure is + * passed to the serial_core.c file. Based on which UART is used, the core file + * passes back the appropriate port structure as an argument to the control + * functions. + */ +static uart_mxc_port mxc_ports[MXC_UART_NR] = { + [0] = { + .port = { + .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR), + .mapbase = UART1_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART1_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .ints_muxed = UART1_MUX_INTS, + .irqs = {UART1_INT2, UART1_INT3}, + .mode = UART1_MODE, + .ir_mode = UART1_IR, + .enabled = UART1_ENABLED, + .hardware_flow = UART1_HW_FLOW, + .cts_threshold = UART1_UCR4_CTSTL, + .dma_enabled = UART1_DMA_ENABLE, + .dma_rxbuf_size = UART1_DMA_RXBUFSIZE, + .rx_threshold = UART1_UFCR_RXTL, + .tx_threshold = UART1_UFCR_TXTL, + .shared = UART1_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART1_TX, + .dma_rx_id = MXC_DMA_UART1_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, + [1] = { + .port = { + .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR), + .mapbase = UART2_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART2_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + .ints_muxed = UART2_MUX_INTS, + .irqs = {UART2_INT2, UART2_INT3}, + .mode = UART2_MODE, + .ir_mode = UART2_IR, + .enabled = UART2_ENABLED, + .hardware_flow = UART2_HW_FLOW, + .cts_threshold = UART2_UCR4_CTSTL, + .dma_enabled = UART2_DMA_ENABLE, + .dma_rxbuf_size = UART2_DMA_RXBUFSIZE, + .rx_threshold = UART2_UFCR_RXTL, + .tx_threshold = UART2_UFCR_TXTL, + .shared = UART2_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART2_TX, + .dma_rx_id = MXC_DMA_UART2_RX, + .rxd_mux = MXC_UART_IR_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, +#if UART3_ENABLED == 1 + [2] = { + .port = { + .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR), + .mapbase = UART3_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART3_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + .ints_muxed = UART3_MUX_INTS, + .irqs = {UART3_INT2, UART3_INT3}, + .mode = UART3_MODE, + .ir_mode = UART3_IR, + .enabled = UART3_ENABLED, + .hardware_flow = UART3_HW_FLOW, + .cts_threshold = UART3_UCR4_CTSTL, + .dma_enabled = UART3_DMA_ENABLE, + .dma_rxbuf_size = UART3_DMA_RXBUFSIZE, + .rx_threshold = UART3_UFCR_RXTL, + .tx_threshold = UART3_UFCR_TXTL, + .shared = UART3_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART3_TX, + .dma_rx_id = MXC_DMA_UART3_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, +#endif +#if UART4_ENABLED == 1 + [3] = { + .port = { + .membase = (void *)IO_ADDRESS(UART4_BASE_ADDR), + .mapbase = UART4_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART4_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 3, + }, + .ints_muxed = UART4_MUX_INTS, + .irqs = {UART4_INT2, UART4_INT3}, + .mode = UART4_MODE, + .ir_mode = UART4_IR, + .enabled = UART4_ENABLED, + .hardware_flow = UART4_HW_FLOW, + .cts_threshold = UART4_UCR4_CTSTL, + .dma_enabled = UART4_DMA_ENABLE, + .dma_rxbuf_size = UART4_DMA_RXBUFSIZE, + .rx_threshold = UART4_UFCR_RXTL, + .tx_threshold = UART4_UFCR_TXTL, + .shared = UART4_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART4_TX, + .dma_rx_id = MXC_DMA_UART4_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, +#endif +#if UART5_ENABLED == 1 + [4] = { + .port = { + .membase = (void *)IO_ADDRESS(UART5_BASE_ADDR), + .mapbase = UART5_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART5_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 4, + }, + .ints_muxed = UART5_MUX_INTS, + .irqs = {UART5_INT2, UART5_INT3}, + .mode = UART5_MODE, + .ir_mode = UART5_IR, + .enabled = UART5_ENABLED, + .hardware_flow = UART5_HW_FLOW, + .cts_threshold = UART5_UCR4_CTSTL, + .dma_enabled = UART5_DMA_ENABLE, + .dma_rxbuf_size = UART5_DMA_RXBUFSIZE, + .rx_threshold = UART5_UFCR_RXTL, + .tx_threshold = UART5_UFCR_TXTL, + .shared = UART5_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART5_TX, + .dma_rx_id = MXC_DMA_UART5_RX, + .rxd_mux = MXC_UART_RXDMUX, + .ir_tx_inv = MXC_IRDA_TX_INV, + .ir_rx_inv = MXC_IRDA_RX_INV, + }, +#endif +}; + +static struct platform_device mxc_uart_device1 = { + .name = "mxcintuart", + .id = 0, + .dev = { + .platform_data = &mxc_ports[0], + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "mxcintuart", + .id = 1, + .dev = { + .platform_data = &mxc_ports[1], + }, +}; + +#if UART3_ENABLED == 1 +static struct platform_device mxc_uart_device3 = { + .name = "mxcintuart", + .id = 2, + .dev = { + .platform_data = &mxc_ports[2], + }, +}; +#endif + +#if UART4_ENABLED == 1 +static struct platform_device mxc_uart_device4 = { + .name = "mxcintuart", + .id = 3, + .dev = { + .platform_data = &mxc_ports[3], + }, +}; +#endif + +#if UART5_ENABLED == 1 +static struct platform_device mxc_uart_device5 = { + .name = "mxcintuart", + .id = 4, + .dev = { + .platform_data = &mxc_ports[4], + }, +}; +#endif + +static int __init mxc_init_uart(void) +{ + /* Register all the MXC UART platform device structures */ + platform_device_register(&mxc_uart_device1); + platform_device_register(&mxc_uart_device2); + + /* Grab ownership of shared UARTs 3 and 4, only when enabled */ +#if UART3_ENABLED == 1 +#if UART3_DMA_ENABLE == 1 + spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C)); +#else + spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A); +#endif /* UART3_DMA_ENABLE */ + platform_device_register(&mxc_uart_device3); +#endif /* UART3_ENABLED */ + +#if UART4_ENABLED == 1 + platform_device_register(&mxc_uart_device4); +#endif /* UART4_ENABLED */ + +#if UART5_ENABLED == 1 + platform_device_register(&mxc_uart_device5); +#endif /* UART5_ENABLED */ + return 0; +} + +#else +static int __init mxc_init_uart(void) +{ + return 0; +} +#endif + +arch_initcall(mxc_init_uart); diff --git a/arch/arm/mach-mx3/serial.h b/arch/arm/mach-mx3/serial.h new file mode 100644 index 000000000000..b2b0a05b9dbd --- /dev/null +++ b/arch/arm/mach-mx3/serial.h @@ -0,0 +1,175 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef __ARCH_ARM_MACH_MX3_SERIAL_H__ +#define __ARCH_ARM_MACH_MX3_SERIAL_H__ + +/*! + * @file mach-mx3/serial.h + * + * @ingroup MSL_MX31 + */ +#include <mach/mxc_uart.h> + +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +#define MXC_UART_NR 5 +/*! + * This option is used to set or clear the RXDMUXSEL bit in control reg 3. + * Certain platforms need this bit to be set in order to receive Irda data. + */ +#define MXC_UART_IR_RXDMUX 0x0004 +/*! + * This option is used to set or clear the RXDMUXSEL bit in control reg 3. + * Certain platforms need this bit to be set in order to receive UART data. + */ +#define MXC_UART_RXDMUX 0x0004 + +/* UART 1 configuration */ +/*! + * This option allows to choose either an interrupt-driven software controlled + * hardware flow control (set this option to 0) or hardware-driven hardware + * flow control (set this option to 1). + */ +/* UART used as wakeup source */ +#define UART1_HW_FLOW 0 +/*! + * This specifies the threshold at which the CTS pin is deasserted by the + * RXFIFO. Set this value in Decimal to anything from 0 to 32 for + * hardware-driven hardware flow control. Read the HW spec while specifying + * this value. When using interrupt-driven software controlled hardware + * flow control set this option to -1. + */ +#define UART1_UCR4_CTSTL 16 +/*! + * This is option to enable (set this option to 1) or disable DMA data transfer + */ +#define UART1_DMA_ENABLE 0 +/*! + * Specify the size of the DMA receive buffer. The minimum buffer size is 512 + * bytes. The buffer size should be a multiple of 256. + */ +#define UART1_DMA_RXBUFSIZE 1024 +/*! + * Specify the MXC UART's Receive Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the RxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_RXTL 16 +/*! + * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the TxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_TXTL 16 +/* UART 2 configuration */ +#define UART2_HW_FLOW 0 +#define UART2_UCR4_CTSTL -1 +#define UART2_DMA_ENABLE 0 +#define UART2_DMA_RXBUFSIZE 512 +#define UART2_UFCR_RXTL 16 +#define UART2_UFCR_TXTL 16 +/* UART 3 configuration */ +#define UART3_HW_FLOW 1 +#define UART3_UCR4_CTSTL 16 +#define UART3_DMA_ENABLE 1 +#define UART3_DMA_RXBUFSIZE 1024 +#define UART3_UFCR_RXTL 16 +#define UART3_UFCR_TXTL 16 +/* UART 4 configuration */ +#define UART4_HW_FLOW 1 +#define UART4_UCR4_CTSTL 16 +#define UART4_DMA_ENABLE 0 +#define UART4_DMA_RXBUFSIZE 512 +#define UART4_UFCR_RXTL 16 +#define UART4_UFCR_TXTL 16 +/* UART 5 configuration */ +#define UART5_HW_FLOW 1 +#define UART5_UCR4_CTSTL 16 +#define UART5_DMA_ENABLE 0 +#define UART5_DMA_RXBUFSIZE 512 +#define UART5_UFCR_RXTL 16 +#define UART5_UFCR_TXTL 16 +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +/* + * Is the MUXED interrupt output sent to the ARM core + */ +#define INTS_NOTMUXED 0 +#define INTS_MUXED 1 +/* UART 1 configuration */ +/*! + * This define specifies whether the muxed ANDed interrupt line or the + * individual interrupts from the UART port is integrated with the ARM core. + * There exists a define like this for each UART port. Valid values that can + * be used are \b INTS_NOTMUXED or \b INTS_MUXED. + */ +#define UART1_MUX_INTS INTS_MUXED +/*! + * This define specifies the transmitter interrupt number or the interrupt + * number of the ANDed interrupt in case the interrupts are muxed. There exists + * a define like this for each UART port. + */ +#define UART1_INT1 MXC_INT_UART1 +/*! + * This define specifies the receiver interrupt number. If the interrupts of + * the UART are muxed, then we specify here a dummy value -1. There exists a + * define like this for each UART port. + */ +#define UART1_INT2 -1 +/*! + * This specifies the master interrupt number. If the interrupts of the UART + * are muxed, then we specify here a dummy value of -1. There exists a define + * like this for each UART port. + */ +#define UART1_INT3 -1 +/*! + * This specifies if the UART is a shared peripheral. It holds the shared + * peripheral number if it is shared or -1 if it is not shared. There exists + * a define like this for each UART port. + */ +#define UART1_SHARED_PERI -1 +/* UART 2 configuration */ +#define UART2_MUX_INTS INTS_MUXED +#define UART2_INT1 MXC_INT_UART2 +#define UART2_INT2 -1 +#define UART2_INT3 -1 +#define UART2_SHARED_PERI -1 +/* UART 3 configuration */ +#define UART3_MUX_INTS INTS_MUXED +#define UART3_INT1 MXC_INT_UART3 +#define UART3_INT2 -1 +#define UART3_INT3 -1 +#define UART3_SHARED_PERI SPBA_UART3 +/* UART 4 configuration */ +#define UART4_MUX_INTS INTS_MUXED +#define UART4_INT1 MXC_INT_UART4 +#define UART4_INT2 -1 +#define UART4_INT3 -1 +#define UART4_SHARED_PERI -1 +/* UART 5 configuration */ +#define UART5_MUX_INTS INTS_MUXED +#define UART5_INT1 MXC_INT_UART5 +#define UART5_INT2 -1 +#define UART5_INT3 -1 +#define UART5_SHARED_PERI -1 + +#endif /* __ARCH_ARM_MACH_MX3_SERIAL_H__ */ diff --git a/arch/arm/mach-mx3/system.c b/arch/arm/mach-mx3/system.c new file mode 100644 index 000000000000..932bf99322d9 --- /dev/null +++ b/arch/arm/mach-mx3/system.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/clk.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <asm/proc-fns.h> +#include <asm/system.h> +#include <mach/clock.h> +#include "crm_regs.h" + +/*! + * @defgroup MSL_MX31 i.MX31 Machine Specific Layer (MSL) + */ + +/*! + * @file mach-mx3/system.c + * @brief This file contains idle and reset functions. + * + * @ingroup MSL_MX31 + */ + +static int clks_initialized = 0; +static struct clk *sdma_clk, *mbx_clk, *ipu_clk, *mpeg_clk, *vpu_clk, *usb_clk, + *rtic_clk, *nfc_clk, *emi_clk; + +extern int mxc_jtag_enabled; + +/*! + * This function puts the CPU into idle mode. It is called by default_idle() + * in process.c file. + */ +void arch_idle(void) +{ + int emi_gated_off = 0; + + /* + * This should do all the clock switching + * and wait for interrupt tricks. + */ + if (!mxc_jtag_enabled) { + if (clks_initialized == 0) { + clks_initialized = 1; + sdma_clk = clk_get(NULL, "sdma_ahb_clk"); + ipu_clk = clk_get(NULL, "ipu_clk"); + if (cpu_is_mx31()) { + mpeg_clk = clk_get(NULL, "mpeg4_clk"); + mbx_clk = clk_get(NULL, "mbx_clk"); + } else { + vpu_clk = clk_get(NULL, "vpu_clk"); + } + usb_clk = clk_get(NULL, "usb_ahb_clk"); + rtic_clk = clk_get(NULL, "rtic_clk"); + nfc_clk = clk_get(NULL, "nfc_clk"); + emi_clk = clk_get(NULL, "emi_clk"); + } + + if ((clk_get_usecount(sdma_clk) == 0) + && (clk_get_usecount(ipu_clk) <= 1) + && (clk_get_usecount(usb_clk) == 0) + && (clk_get_usecount(rtic_clk) == 0) + && (clk_get_usecount(mpeg_clk) == 0) + && (clk_get_usecount(mbx_clk) == 0) + && (clk_get_usecount(nfc_clk) == 0) + && (clk_get_usecount(vpu_clk) == 0)) { + emi_gated_off = 1; + clk_disable(emi_clk); + } + + cpu_do_idle(); + if (emi_gated_off == 1) { + clk_enable(emi_clk); + } + } +} + +/* + * This function resets the system. It is called by machine_restart(). + * + * @param mode indicates different kinds of resets + */ +void arch_reset(char mode) +{ + /* Assert SRS signal */ + mxc_wd_reset(); +} diff --git a/arch/arm/mach-mx3/usb.h b/arch/arm/mach-mx3/usb.h new file mode 100644 index 000000000000..5a7170367773 --- /dev/null +++ b/arch/arm/mach-mx3/usb.h @@ -0,0 +1,116 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + + +extern int usbotg_init(struct platform_device *pdev); +extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata); +extern int gpio_usbotg_fs_active(void); +extern void gpio_usbotg_fs_inactive(void); +extern int gpio_usbotg_hs_active(void); +extern void gpio_usbotg_hs_inactive(void); +extern struct platform_device *host_pdev_register(struct resource *res, + int n_res, struct fsl_usb2_platform_data *config); + +extern int fsl_usb_host_init(struct platform_device *pdev); +extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata); +extern int gpio_usbh1_active(void); +extern void gpio_usbh1_inactive(void); +extern int gpio_usbh2_active(void); +extern void gpio_usbh2_inactive(void); + +/* + * Determine which platform_data struct to use for the DR controller, + * based on which transceiver is configured. + * PDATA is a pointer to it. + */ +#if defined(CONFIG_ISP1504_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_1504_config; +#define PDATA (&dr_1504_config) +#elif defined(CONFIG_ISP1301_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_1301_config; +#define PDATA (&dr_1301_config) +#elif defined(CONFIG_MC13783_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_13783_config; +#define PDATA (&dr_13783_config) +#endif + + +/* + * Used to set pdata->operating_mode before registering the platform_device. + * If OTG is configured, the controller operates in OTG mode, + * otherwise it's either host or device. + */ +#ifdef CONFIG_USB_OTG +#define DR_UDC_MODE FSL_USB2_DR_OTG +#define DR_HOST_MODE FSL_USB2_DR_OTG +#else +#define DR_UDC_MODE FSL_USB2_DR_DEVICE +#define DR_HOST_MODE FSL_USB2_DR_HOST +#endif + + +#ifdef CONFIG_USB_EHCI_ARC_OTG +static inline void dr_register_host(struct resource *r, int rs) +{ + PDATA->operating_mode = DR_HOST_MODE; + host_pdev_register(r, rs, PDATA); +} +#else +static inline void dr_register_host(struct resource *r, int rs) +{ +} +#endif + +#ifdef CONFIG_USB_GADGET_ARC +static struct platform_device dr_udc_device; + +static inline void dr_register_udc(void) +{ + PDATA->operating_mode = DR_UDC_MODE; + dr_udc_device.dev.platform_data = PDATA; + + if (platform_device_register(&dr_udc_device)) + printk(KERN_ERR "usb: can't register DR gadget\n"); + else + printk(KERN_INFO "usb: DR gadget (%s) registered\n", + PDATA->transceiver); +} +#else +static inline void dr_register_udc(void) +{ +} +#endif + +#ifdef CONFIG_USB_OTG +static struct platform_device dr_otg_device; + +/* + * set the proper operating_mode and + * platform_data pointer, then register the + * device. + */ +static inline void dr_register_otg(void) +{ + PDATA->operating_mode = FSL_USB2_DR_OTG; + dr_otg_device.dev.platform_data = PDATA; + + if (platform_device_register(&dr_otg_device)) + printk(KERN_ERR "usb: can't register otg device\n"); + else + printk(KERN_INFO "usb: DR OTG registered\n"); +} +#else +static inline void dr_register_otg(void) +{ +} +#endif diff --git a/arch/arm/mach-mx3/usb_dr.c b/arch/arm/mach-mx3/usb_dr.c new file mode 100644 index 000000000000..7331463173e9 --- /dev/null +++ b/arch/arm/mach-mx3/usb_dr.c @@ -0,0 +1,129 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <mach/hardware.h> +#include <mach/arc_otg.h> +#include "usb.h" + +/* + * platform data structs + * - Which one to use is determined by CONFIG options in usb.h + * - operating_mode plugged at run time + */ +static struct fsl_usb2_platform_data __maybe_unused dr_13783_config = { + .name = "DR", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .phy_mode = FSL_USB2_PHY_SERIAL, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "mc13783", +}; + +static struct fsl_usb2_platform_data __maybe_unused dr_1301_config = { + .name = "DR", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .phy_mode = FSL_USB2_PHY_SERIAL, + .power_budget = 150, /* 150 mA max power */ + .gpio_usb_active = gpio_usbotg_fs_active, + .gpio_usb_inactive = gpio_usbotg_fs_inactive, + .transceiver = "isp1301", +}; + +static struct fsl_usb2_platform_data __maybe_unused dr_1504_config = { + .name = "DR", + .platform_init = usbotg_init, + .platform_uninit = usbotg_uninit, + .phy_mode = FSL_USB2_PHY_ULPI, + .power_budget = 150, /* 150 mA max power */ + .gpio_usb_active = gpio_usbotg_hs_active, + .gpio_usb_inactive = gpio_usbotg_hs_inactive, + .transceiver = "isp1504", +}; + + +/* + * resources + */ +static struct resource otg_resources[] = { + [0] = { + .start = (u32)(USB_OTGREGS_BASE), + .end = (u32)(USB_OTGREGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB3, + .flags = IORESOURCE_IRQ, + }, +}; + + +static u64 dr_udc_dmamask = ~(u32) 0; +static void dr_udc_release(struct device *dev) +{ +} + +static u64 dr_otg_dmamask = ~(u32) 0; +static void dr_otg_release(struct device *dev) +{ +} + +/* + * platform device structs + * dev.platform_data field plugged at run time + */ +static struct platform_device __maybe_unused dr_udc_device = { + .name = "fsl-usb2-udc", + .id = -1, + .dev = { + .release = dr_udc_release, + .dma_mask = &dr_udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +static struct platform_device __maybe_unused dr_otg_device = { + .name = "fsl-usb2-otg", + .id = -1, + .dev = { + .release = dr_otg_release, + .dma_mask = &dr_otg_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +static int __init usb_dr_init(void) +{ + pr_debug("%s: \n", __func__); + + dr_register_otg(); + dr_register_host(otg_resources, ARRAY_SIZE(otg_resources)); + dr_register_udc(); +#ifdef CONFIG_USB_GADGET_WAKE_UP + /* set udc may and should wakeup */ + device_init_wakeup(&(dr_udc_device.dev), 1); +#endif + return 0; +} + +module_init(usb_dr_init); diff --git a/arch/arm/mach-mx3/usb_h1.c b/arch/arm/mach-mx3/usb_h1.c new file mode 100644 index 000000000000..1119ba6edd06 --- /dev/null +++ b/arch/arm/mach-mx3/usb_h1.c @@ -0,0 +1,54 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <mach/arc_otg.h> +#include <mach/hardware.h> +#include "usb.h" + +static struct fsl_usb2_platform_data usbh1_config = { + .name = "Host 1", + .platform_init = fsl_usb_host_init, + .platform_uninit = fsl_usb_host_uninit, + .operating_mode = FSL_USB2_MPH_HOST, + .phy_mode = FSL_USB2_PHY_SERIAL, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh1_active, + .gpio_usb_inactive = gpio_usbh1_inactive, + .transceiver = "serial", +}; + +static struct resource usbh1_resources[] = { + [0] = { + .start = (u32) (USB_H1REGS_BASE), + .end = (u32) (USB_H1REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB1, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init usbh1_init(void) +{ + pr_debug("%s: \n", __func__); + + host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources), + &usbh1_config); + return 0; +} +module_init(usbh1_init); diff --git a/arch/arm/mach-mx3/usb_h2.c b/arch/arm/mach-mx3/usb_h2.c new file mode 100644 index 000000000000..b95b06866c47 --- /dev/null +++ b/arch/arm/mach-mx3/usb_h2.c @@ -0,0 +1,70 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/mach-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_ULPI, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh2_active, + .gpio_usb_inactive = gpio_usbh2_inactive, + .transceiver = "isp1504", +}; + +static struct resource usbh2_resources[] = { + [0] = { + .start = (u32) (USB_H2REGS_BASE), + .end = (u32) (USB_H2REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB2, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init usbh2_init(void) +{ + pr_debug("%s: \n", __func__); + + if (machine_is_mx31_3ds()) { + struct regulator *usbh2_regux; + usbh2_config.xcvr_pwr = + kmalloc(sizeof(struct fsl_xcvr_power), GFP_KERNEL); + if (!(usbh2_config.xcvr_pwr)) + return -ENOMEM; + + usbh2_regux = regulator_get(NULL, "GPO1"); + usbh2_config.xcvr_pwr->regu1 = usbh2_regux; + usbh2_regux = regulator_get(NULL, "GPO3"); + usbh2_config.xcvr_pwr->regu2 = usbh2_regux; + } + + host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources), + &usbh2_config); + return 0; +} +module_init(usbh2_init); |