summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAdam Lussier <adam.lussier@timesys.com>2013-02-25 17:19:04 -0500
committerAdam Lussier <adam.lussier@timesys.com>2013-02-25 17:19:04 -0500
commitf962cbcefdfad22ffff41e19ad4c5ff58815c05c (patch)
treee9424582f1fdc92d360ff58c831ddf801a268e3f /arch
parent15f55e0b22f8953b56fb5d6bdf8b770228f2f449 (diff)
parent16af5ee7d9556c47b332788e4107cbed5ee7ec10 (diff)
Merge remote-tracking branch 'github/3.0-pcm052' into 3.0-pcm0523.0-pcm052-ts2
Release 3.0-ts2: enable USB support for the phyCORE Vybrid
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/configs/mvf600_defconfig103
-rw-r--r--arch/arm/mach-mvf/Kconfig1
-rw-r--r--arch/arm/mach-mvf/Makefile4
-rw-r--r--arch/arm/mach-mvf/board-pcm052.c15
-rw-r--r--arch/arm/mach-mvf/board-twr-vf700.c39
-rw-r--r--arch/arm/mach-mvf/clock.c50
-rw-r--r--arch/arm/mach-mvf/cpu.c3
-rw-r--r--arch/arm/mach-mvf/crm_regs.h1
-rw-r--r--arch/arm/mach-mvf/devices-mvf.h42
-rw-r--r--arch/arm/mach-mvf/irq.c10
-rw-r--r--arch/arm/mach-mvf/mvf_suspend.S484
-rw-r--r--arch/arm/mach-mvf/pm.c312
-rw-r--r--arch/arm/mach-mvf/regs-pm.h77
-rw-r--r--arch/arm/mach-mvf/regs-src.h45
-rw-r--r--arch/arm/mach-mvf/system.c139
-rw-r--r--arch/arm/mach-mvf/usb_dr.c310
-rw-r--r--arch/arm/mach-mvf/usb_dr2.c199
-rwxr-xr-xarch/arm/plat-mxc/devices/Kconfig8
-rwxr-xr-xarch/arm/plat-mxc/devices/Makefile2
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c12
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c29
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-asrc.c18
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pm.c7
-rw-r--r--arch/arm/plat-mxc/devices/platform-mvf-adc.c50
-rw-r--r--arch/arm/plat-mxc/devices/platform-mvf-caam.c107
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-ehci.c15
-rwxr-xr-xarch/arm/plat-mxc/include/mach/arc_otg.h2
-rwxr-xr-xarch/arm/plat-mxc/include/mach/devices-common.h26
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mvf.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/mvf.h54
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc.h14
-rwxr-xr-xarch/arm/plat-mxc/usb_common.c3
-rwxr-xr-xarch/arm/plat-mxc/usb_wakeup.c25
33 files changed, 2090 insertions, 134 deletions
diff --git a/arch/arm/configs/mvf600_defconfig b/arch/arm/configs/mvf600_defconfig
index 23646435c6af..648e8f5e4d13 100644
--- a/arch/arm/configs/mvf600_defconfig
+++ b/arch/arm/configs/mvf600_defconfig
@@ -178,7 +178,7 @@ CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_FREEZER is not set
+CONFIG_FREEZER=y
#
# System Type
@@ -246,6 +246,7 @@ CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_MVF_ADC=y
CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
@@ -325,14 +326,20 @@ CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
-# CONFIG_CACHE_L2X0 is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_DMA_MEM_BUFFERABLE=y
CONFIG_CPU_HAS_PMU=y
# CONFIG_ARM_ERRATA_430973 is not set
# CONFIG_ARM_ERRATA_458693 is not set
# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_GIC=y
@@ -342,6 +349,7 @@ CONFIG_ARM_GIC=y
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
+# CONFIG_PL310_ERRATA_769419 is not set
#
# Kernel Features
@@ -419,7 +427,9 @@ CONFIG_CMDLINE_FROM_BOOTLOADER=y
#
# At least one emulation must be selected
#
-# CONFIG_VFP is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
#
# Userspace binary formats
@@ -433,7 +443,9 @@ CONFIG_HAVE_AOUT=y
#
# Power management options
#
-# CONFIG_SUSPEND is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
CONFIG_PM_RUNTIME=y
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
@@ -652,7 +664,41 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_MG_DISK is not set
# CONFIG_BLK_DEV_RBD is not set
# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_INTEL_MID_PTI is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MVF_ADC=y
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -748,6 +794,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_KS8851 is not set
# CONFIG_KS8851_MLL is not set
CONFIG_FEC=y
+# CONFIG_FEC1 is not set
# CONFIG_FEC_1588 is not set
# CONFIG_FTMAC100 is not set
# CONFIG_NETDEV_1000 is not set
@@ -795,6 +842,7 @@ CONFIG_INPUT_POLLDEV=y
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
+# CONFIG_TSDEV_COMPATIBLE is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
@@ -858,6 +906,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ST1232 is not set
# CONFIG_TOUCHSCREEN_P1003 is not set
# CONFIG_TOUCHSCREEN_TPS6507X is not set
+# CONFIG_TOUCHSCREEN_CRTOUCH is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_ATI_REMOTE is not set
@@ -975,10 +1024,11 @@ CONFIG_SPI_MASTER=y
#
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_MVF_QSPI is not set
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_IMX is not set
CONFIG_SPI_MVF=y
-# CONFIG_SPI_MVF_DSPI_EDMA is not set
+CONFIG_SPI_MVF_DSPI_EDMA=y
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
@@ -1434,7 +1484,8 @@ CONFIG_DMADEVICES=y
# DMA Devices
#
# CONFIG_DW_DMAC is not set
-CONFIG_MCF_EDMA=y
+CONFIG_MVF_EDMA=y
+CONFIG_MVF_EDMA_TEST=m
# CONFIG_MXC_PXP is not set
# CONFIG_MXC_PXP_V2 is not set
# CONFIG_TIMB_DMA is not set
@@ -1499,6 +1550,7 @@ CONFIG_CLKSRC_MMIO=y
#
# MXC Asynchronous Sample Rate Converter support
#
+CONFIG_MXC_ASRC=y
#
# MXC Bluetooth support
@@ -1758,25 +1810,28 @@ CONFIG_CRYPTO=y
#
# Crypto core or helper
#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_TEST=m
-# CONFIG_CRYPTO_CRYPTODEV is not set
+CONFIG_CRYPTO_CRYPTODEV=y
#
# Authenticated Encryption with Associated Data
@@ -1788,10 +1843,10 @@ CONFIG_CRYPTO_TEST=m
#
# Block modes
#
-CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CBC is not set
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
@@ -1810,7 +1865,7 @@ CONFIG_CRYPTO_ECB=y
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
-CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
@@ -1826,7 +1881,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
#
CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
@@ -1850,10 +1905,24 @@ CONFIG_CRYPTO_LZO=y
#
# Random Number Generation
#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_USER_API_HASH is not set
-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
+# CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE=7
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
# CONFIG_BINARY_PRINTF is not set
#
diff --git a/arch/arm/mach-mvf/Kconfig b/arch/arm/mach-mvf/Kconfig
index 23df64879243..0ef1f8a09d37 100644
--- a/arch/arm/mach-mvf/Kconfig
+++ b/arch/arm/mach-mvf/Kconfig
@@ -54,6 +54,7 @@ config MACH_MVFA5_TWR_VF700
select IMX_HAVE_PLATFORM_MVF_DCU
select IMX_HAVE_PLATFORM_MVF_SAI
select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MVF_CAAM
help
Include support for MVF TWR-VF700 platform. This includes specific
configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mvf/Makefile b/arch/arm/mach-mvf/Makefile
index 07f33a555dcb..fad70a4a9dc7 100644
--- a/arch/arm/mach-mvf/Makefile
+++ b/arch/arm/mach-mvf/Makefile
@@ -3,9 +3,9 @@
#
# Object file lists.
-obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o mvf_fec.o usb_dr.o usb_dr2.o
+obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o mvf_fec.o usb_dr.o usb_dr2.o pm.o
obj-y += l2switch.o
-obj-$(CONFIG_ARCH_MVFA5) += clock.o
+obj-$(CONFIG_ARCH_MVFA5) += clock.o mvf_suspend.o
obj-$(CONFIG_MACH_MVFA5_TWR_VF700) += board-twr-vf700.o
obj-$(CONFIG_MACH_PCM052) += board-pcm052.o
diff --git a/arch/arm/mach-mvf/board-pcm052.c b/arch/arm/mach-mvf/board-pcm052.c
index 08b071f1dcf7..84bd65623ebb 100644
--- a/arch/arm/mach-mvf/board-pcm052.c
+++ b/arch/arm/mach-mvf/board-pcm052.c
@@ -195,7 +195,7 @@ static iomux_v3_cfg_t pcm052_pads[] = {
#ifdef PCM952_REV0
MVF600_PAD6_PTA16__USB0_VBUS_EN,
#else
- MVF600_PAD134_PTA7__USB0_VBUS_EN,
+ MVF600_PAD134_PTA7__USB_VBUS_EN,
#endif
MVF600_PAD7_PTA17__USB_OC_N,
@@ -275,7 +275,7 @@ static struct switch_platform_data switch_data __initdata = {
};
static int pcm052_spi_cs[] = {
- 134,
+ 41,
};
static const struct spi_mvf_master pcm052_spi_data __initconst = {
@@ -479,14 +479,15 @@ static struct led_pwm_platform_data mvf_led_data __initdata = {
.leds = &mvf_led,
};
+#define USB_VBUS_ENABLE_PIN 134
static void __init pcm052_init_usb(void)
{
- imx_otg_base = MVF_IO_ADDRESS(MVF_USBC0_BASE_ADDR);
- /*mvf_set_otghost_vbus_func(pcm052_usbotg_vbus);*/
-#ifdef CONFIG_USB_GADGET_ARC
- mvf_usb_dr_init();
-#endif
+ gpio_request_one(USB_VBUS_ENABLE_PIN, GPIOF_OUT_INIT_LOW, "VBUS_EN");
+ msleep(2);
+ gpio_set_value(USB_VBUS_ENABLE_PIN, 1);
+
#ifdef CONFIG_USB_EHCI_ARC
+ mvf_usb_dr_init();
mvf_usb_dr2_init();
#endif
}
diff --git a/arch/arm/mach-mvf/board-twr-vf700.c b/arch/arm/mach-mvf/board-twr-vf700.c
index 03cc6ad51788..01fd4dc364cc 100644
--- a/arch/arm/mach-mvf/board-twr-vf700.c
+++ b/arch/arm/mach-mvf/board-twr-vf700.c
@@ -72,6 +72,7 @@
#include <mach/mipi_dsi.h>
#include <mach/mipi_csi2.h>
#include <mach/fsl_l2_switch.h>
+#include <mach/mxc.h>
#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -364,22 +365,20 @@ static void spi_device_init(void)
ARRAY_SIZE(mvf_spi_board_info));
}
-#if 1
-static void vf700_suspend_enter(void)
+static void vf600_suspend_enter(void)
{
/* suspend preparation */
}
-static void vf700_suspend_exit(void)
+static void vf600_suspend_exit(void)
{
/* resmue resore */
}
-static const struct pm_platform_data mvf_vf700_pm_data __initconst = {
+static const struct pm_platform_data mvf_vf600_pm_data __initconst = {
.name = "mvf_pm",
- .suspend_enter = vf700_suspend_enter,
- .suspend_exit = vf700_suspend_exit,
+ .suspend_enter = vf600_suspend_enter,
+ .suspend_exit = vf600_suspend_exit,
};
-#endif
static struct mvf_dcu_platform_data mvf_dcu_pdata = {
.mode_str = "480x272",
@@ -427,16 +426,26 @@ static struct led_pwm_platform_data mvf_led_data __initdata = {
.leds = &mvf_led,
};
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 3,
+};
+
static void __init mvf_twr_init_usb(void)
{
imx_otg_base = MVF_IO_ADDRESS(MVF_USBC0_BASE_ADDR);
/*mvf_set_otghost_vbus_func(mvf_twr_usbotg_vbus);*/
-#ifdef CONFIG_USB_GADGET_ARC
- mvf_usb_dr_init();
-#endif
#ifdef CONFIG_USB_EHCI_ARC
mvf_usb_dr2_init();
#endif
+#ifdef CONFIG_USB_GADGET_ARC
+ mvf_usb_dr_init();
+#endif
+}
+
+static void __init mvf_init_adc(void)
+{
+ mvf_add_adc(0);
}
/*!
@@ -458,6 +467,12 @@ static void __init mvf_board_init(void)
mvf_add_snvs_rtc();
+ mvf_init_adc();
+
+ mvf_add_pm_imx(0, &mvf_vf600_pm_data);
+
+ mvf700_add_caam();
+
mvf_add_sdhci_esdhc_imx(1, &mvfa5_sd1_data);
mvf_add_imx_i2c(0, &mvf600_i2c_data);
@@ -482,6 +497,10 @@ static void __init mvf_board_init(void)
mvf_add_mxc_pwm(0);
mvf_add_pwm_leds(&mvf_led_data);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ mvf_add_asrc(&imx_asrc_data);
+
}
static void __init mvf_timer_init(void)
diff --git a/arch/arm/mach-mvf/clock.c b/arch/arm/mach-mvf/clock.c
index 25e1079165dd..74ce8a9f290e 100644
--- a/arch/arm/mach-mvf/clock.c
+++ b/arch/arm/mach-mvf/clock.c
@@ -670,10 +670,12 @@ static int _clk_pll3_usb_otg_set_rate(struct clk *clk, unsigned long rate)
else
return -EINVAL;
+#ifndef CONFIG_MACH_PCM052
reg = __raw_readl(PLL3_480_USB1_BASE_ADDR);
reg &= ~ANADIG_PLL_480_DIV_SELECT_MASK;
reg |= div;
__raw_writel(reg, PLL3_480_USB1_BASE_ADDR);
+#endif
return 0;
}
@@ -1613,6 +1615,14 @@ static struct clk clko2_clk = {
.get_rate = _clk_clko2_get_rate,
.round_rate = _clk_clko_round_rate,
};
+static struct clk caam_clk = {
+ __INIT_CLK_DEBUG(caam_clk)
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR11,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
static struct clk pit_clk = {
__INIT_CLK_DEBUG(pit_clk)
@@ -1626,6 +1636,18 @@ static struct clk pit_clk = {
.get_rate = _clk_uart_get_rate,
};
+static struct clk adc_clk[] = {
+ {
+ __INIT_CLK_DEBUG(adc_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
static struct clk i2c_clk[] = {
{
__INIT_CLK_DEBUG(i2c_clk_0)
@@ -1845,6 +1867,29 @@ static struct clk qspi1_clk = {
.get_rate = _clk_qspi1_get_rate,
};
+static int _clk_asrc_serial_set_rate(struct clk *clk, unsigned long rate)
+{
+ return 0;
+}
+
+static struct clk asrc_clk[] = {
+ {
+ __INIT_CLK_DEBUG(asrc_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(asrc_serial_clk)
+ .id = 1,
+ .parent = &audio_external_clk,
+ .set_rate = _clk_asrc_serial_set_rate,
+ },
+};
+
static struct clk dummy_clk = {
.id = 0,
};
@@ -1890,6 +1935,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("pit", NULL, pit_clk),
_REGISTER_CLOCK("fec.0", NULL, enet_clk[0]),
_REGISTER_CLOCK("fec.1", NULL, enet_clk[1]),
+ _REGISTER_CLOCK("mvf-adc.0", NULL, adc_clk[0]),
_REGISTER_CLOCK("switch.0", NULL, enet_clk[0]),
_REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk),
_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc1_clk),
@@ -1902,10 +1948,12 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "mvf-usb.1", usb_phy1_clk),
_REGISTER_CLOCK(NULL, "pwm", ftm_pwm_clk),
_REGISTER_CLOCK("mvf-qspi.0", NULL, qspi0_clk),
+ _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk[0]),
+ _REGISTER_CLOCK(NULL, "asrc_serial_clk", asrc_clk[1]),
+ _REGISTER_CLOCK(NULL, "caam_clk", caam_clk),
};
static void clk_tree_init(void)
-
{
unsigned int reg = 0xffffffff;
diff --git a/arch/arm/mach-mvf/cpu.c b/arch/arm/mach-mvf/cpu.c
index 2254ac5974c5..4c6d018cd076 100644
--- a/arch/arm/mach-mvf/cpu.c
+++ b/arch/arm/mach-mvf/cpu.c
@@ -81,8 +81,7 @@ EXPORT_SYMBOL(mvf_revision);
static int __init post_cpu_init(void)
{
-
- /*iram_init(MVF_IRAM_BASE_ADDR, MVF_IRAM_SIZE);*/
+ iram_init(MVF_IRAM_BASE_ADDR, MVF_IRAM_SIZE);
/* Move wait routine into iRAM */
ccm_base = MVF_IO_ADDRESS(MVF_CCM_BASE_ADDR);
diff --git a/arch/arm/mach-mvf/crm_regs.h b/arch/arm/mach-mvf/crm_regs.h
index 78604eb96447..57fac5bbe973 100644
--- a/arch/arm/mach-mvf/crm_regs.h
+++ b/arch/arm/mach-mvf/crm_regs.h
@@ -50,6 +50,7 @@
#define PFD_480_BASE_ADDR (MXC_PLL_BASE + 0xF0)
#define PFD_528_BASE_ADDR (MXC_PLL_BASE + 0x100)
#define PFD_528SYS_BASE_ADDR (MXC_PLL_BASE + 0x2B0)
+#define ANADIG_2P5_ADDR (MXC_PLL_BASE + 0x130)
#define ANADIG_MISC0_REG (MXC_PLL_BASE + 0x150)
#define ANADIG_MISC1_REG (MXC_PLL_BASE + 0x160)
#define PLL_PFD_480_USB1 (MXC_PLL_BASE + 0xF0)
diff --git a/arch/arm/mach-mvf/devices-mvf.h b/arch/arm/mach-mvf/devices-mvf.h
index 61792fb34530..f4ec88b062ac 100644
--- a/arch/arm/mach-mvf/devices-mvf.h
+++ b/arch/arm/mach-mvf/devices-mvf.h
@@ -52,6 +52,15 @@ extern const struct imx_mxc_nand_data mvf_nand_data __initconst;
#define mvf_add_nand(pdata) \
imx_add_mxc_nand(&mvf_nand_data, pdata)
+#ifdef CONFIG_MACH_PCM052
+extern const struct imx_fsl_usb2_udc_data mvf_fsl_usb2_udc_data[] __initconst;
+#define mvf_add_fsl_usb2_udc(id, pdata) \
+ imx_add_fsl_usb2_udc(&mvf_fsl_usb2_udc_data[id], pdata)
+
+extern const struct imx_mxc_ehci_data mvf_mxc_ehci_otg_data[] __initconst;
+#define mvf_add_fsl_ehci_otg(id, pdata) \
+ imx_add_fsl_ehci(&mvf_mxc_ehci_otg_data[id], pdata)
+#else
extern const struct imx_fsl_usb2_udc_data mvf_fsl_usb2_udc_data __initconst;
#define mvf_add_fsl_usb2_udc(pdata) \
imx_add_fsl_usb2_udc(&mvf_fsl_usb2_udc_data, pdata)
@@ -59,24 +68,43 @@ extern const struct imx_fsl_usb2_udc_data mvf_fsl_usb2_udc_data __initconst;
extern const struct imx_mxc_ehci_data mvf_mxc_ehci_otg_data __initconst;
#define mvf_add_fsl_ehci_otg(pdata) \
imx_add_fsl_ehci(&mvf_mxc_ehci_otg_data, pdata)
+#endif
extern const struct imx_mxc_ehci_data mvf_mxc_ehci_hs_data[] __initconst;
+#ifdef CONFIG_MACH_PCM052
+#define mvf_add_fsl_ehci_hs(id, pdata) \
+ imx_add_fsl_ehci(&mvf_mxc_ehci_hs_data[id], pdata)
+#else
#define mvf_add_fsl_ehci_hs(id, pdata) \
imx_add_fsl_ehci(&mvf_mxc_ehci_hs_data[id - 1], pdata)
+#endif
extern const struct imx_fsl_usb2_otg_data mvf_fsl_usb2_otg_data __initconst;
#define mvf_add_fsl_usb2_otg(pdata) \
imx_add_fsl_usb2_otg(&mvf_fsl_usb2_otg_data, pdata)
extern
-const struct imx_fsl_usb2_wakeup_data mvf_fsl_otg_wakeup_data __initconst;
-#define mvf_add_fsl_usb2_otg_wakeup(pdata) \
- imx_add_fsl_usb2_wakeup(&mvf_fsl_otg_wakeup_data, pdata)
+const struct imx_fsl_usb2_wakeup_data mvf_fsl_otg_wakeup_data[] __initconst;
+#ifdef CONFIG_MACH_PCM052
+#define mvf_add_fsl_usb2_ehci_otg_wakeup(id, pdata) \
+ imx_add_fsl_usb2_wakeup(&mvf_fsl_otg_wakeup_data[id], pdata)
+#define mvf_add_fsl_usb2_udc_wakeup(id, pdata) \
+ imx_add_fsl_usb2_wakeup(&mvf_fsl_otg_wakeup_data[id], pdata)
+#else
+#define mvf_add_fsl_usb2_ehci_otg_wakeup(pdata) \
+ imx_add_fsl_usb2_wakeup(&mvf_fsl_otg_wakeup_data[1], pdata)
+#define mvf_add_fsl_usb2_udc_wakeup(pdata) \
+ imx_add_fsl_usb2_wakeup(&mvf_fsl_otg_wakeup_data[0], pdata)
+#endif
extern
const struct imx_fsl_usb2_wakeup_data mvf_fsl_hs_wakeup_data[] __initconst;
+#ifdef CONFIG_MACH_PCM052
+#define mvf_add_fsl_usb2_hs_wakeup(id, pdata) \
+ imx_add_fsl_usb2_wakeup(&mvf_fsl_hs_wakeup_data[id], pdata)
#define mvf_add_fsl_usb2_hs_wakeup(id, pdata) \
imx_add_fsl_usb2_wakeup(&mvf_fsl_hs_wakeup_data[id - 1], pdata)
+#endif
extern const struct imx_imx_esai_data mvf_imx_esai_data[] __initconst;
#define mvf_add_imx_esai(id, pdata) \
@@ -142,6 +170,10 @@ extern const struct imx_imx2_wdt_data mvf_imx2_wdt_data[] __initconst;
#define mvf_add_imx2_wdt(id, pdata) \
imx_add_imx2_wdt(&mvf_imx2_wdt_data[id])
+extern const struct mvf_adc_data mvfa5_adc_data[] __initconst;
+#define mvf_add_adc(id) \
+ mvf_add_adcdev(&mvfa5_adc_data[id])
+
extern const struct imx_imx2_wdt_data fsl_imx2_wdt_data[] __initconst;
#define mvf_add_wdt(id) \
imx_add_imx2_wdt(&fsl_imx2_wdt_data[id])
@@ -218,3 +250,7 @@ extern const struct imx_epdc_data mvf_epdc_data __initconst;
#define mvf_add_pwm_leds(pdata) \
imx_add_platform_device("leds_pwm", 0, NULL, 0, pdata, sizeof(*pdata))
+
+extern const struct mvf_caam_data mvf_caam_data __initconst;
+#define mvf700_add_caam() \
+ mvf_add_caam(&mvf_caam_data)
diff --git a/arch/arm/mach-mvf/irq.c b/arch/arm/mach-mvf/irq.c
index c3e7b9291faa..89c7d382173f 100644
--- a/arch/arm/mach-mvf/irq.c
+++ b/arch/arm/mach-mvf/irq.c
@@ -36,9 +36,9 @@ static int mvf_gic_irq_set_wake(struct irq_data *d, unsigned int enable)
if (enable) {
gpc_wake_irq[d->irq / 32 - 1] |= 1 << (d->irq % 32);
- printk(KERN_INFO "add wake up source irq %d\n", d->irq);
+ printk(KERN_DEBUG "add wake up source irq %d\n", d->irq);
} else {
- printk(KERN_INFO "remove wake up source irq %d\n", d->irq);
+ printk(KERN_DEBUG "remove wake up source irq %d\n", d->irq);
gpc_wake_irq[d->irq / 32 - 1] &= ~(1 << (d->irq % 32));
}
return 0;
@@ -48,6 +48,7 @@ void mvf_init_irq(void)
unsigned int i;
void __iomem *int_router_base =
MVF_IO_ADDRESS(MVF_MSCM_INT_ROUTER_BASE);
+ struct irq_desc *desc;
/* start offset if private timer irq id, which is 29.
* ID table:
@@ -60,6 +61,11 @@ void mvf_init_irq(void)
gic_init(0, 27, MVF_IO_ADDRESS(MVF_INTD_BASE_ADDR),
MVF_IO_ADDRESS(MVF_SCUGIC_BASE_ADDR + 0x100));
+ for (i = MXC_INT_START; i <= MXC_INT_END; i++) {
+ desc = irq_to_desc(i);
+ desc->irq_data.chip->irq_set_wake = mvf_gic_irq_set_wake;
+ }
+
mvf_register_gpios();
for (i = 0; i < 112; i++)
diff --git a/arch/arm/mach-mvf/mvf_suspend.S b/arch/arm/mach-mvf/mvf_suspend.S
new file mode 100644
index 000000000000..ce9205162538
--- /dev/null
+++ b/arch/arm/mach-mvf/mvf_suspend.S
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+#include <asm/memory.h>
+#include <mach/mvf.h>
+#include "regs-src.h"
+#include "crm_regs.h"
+
+#define PERIPBASE_VIRT_OFFSET 0xb2000000
+#define TTRBIT_MASK 0xffffc000
+#define TABLE_INDEX_MASK 0xfff00000
+#define TABLE_ENTRY 0x00000c02
+#define CACHE_DISABLE_MASK 0xfffffffb
+#define IRAM_SUSPEND_SIZE (1 << 15)
+
+/*************************************************************
+mvf_suspend:
+
+Suspend the processor (eg, wait for interrupt).
+
+r1: iram_paddr
+r2: suspend_iram_base
+*************************************************************/
+
+ .macro mvf_stop_mode_enter
+
+ ldr r3, =MVF_ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ /* pll7 disable */
+ ldr r4, [r3, #0x20]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x20]
+
+ /* pll3 disable */
+ ldr r4, [r3, #0x10]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x10]
+
+ /* pll4 disable */
+ ldr r4, [r3, #0x70]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x70]
+
+ /* pll6 disable */
+ ldr r4, [r3, #0xa0]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0xa0]
+
+ /* pll5 disable */
+ ldr r4, [r3, #0xe0]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0xe0]
+
+ /* pll1 disable */
+ ldr r4, [r3, #0x270]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x270]
+
+ /* stop mode is masked to Anatop */
+ ldr r3, =MVF_CCM_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ ldr r4, [r3, #0x2c]
+ bic r4, r4, #0x100
+ str r4, [r3, #0x2c]
+
+ ldr r3, =MVF_GPC_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ /* ensure power domain 0 */
+ ldr r4, [r3, #0x0]
+ bic r4, r4, #0x01
+ str r4, [r3, #0x0]
+
+ /* enable deep sleep for memories */
+ ldr r4, [r3, #0x0]
+ orr r4, r4, #0x80
+ str r4, [r3, #0x0]
+
+ /* disable well bias */
+ ldr r4, [r3, #0x0]
+ bic r4, r4, #0x10
+ str r4, [r3, #0x0]
+
+ /* turn off HPREG in stop mode */
+ ldr r4, [r3, #0x0]
+ orr r4, r4, #0x08
+ str r4, [r3, #0x0]
+
+ /* gpc_lpmr set stop mode */
+ ldr r4, =0x02
+ str r4, [r3, #0x40]
+
+ .endm
+
+ .macro mvf_lpstop_mode_enter
+
+ ldr r3, =MVF_ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ /* pll7 disable */
+ ldr r4, [r3, #0x20]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x20]
+
+ /* pll3 disable */
+ ldr r4, [r3, #0x10]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x10]
+
+ /* pll4 disable */
+ ldr r4, [r3, #0x70]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x70]
+
+ /* pll6 disable */
+ ldr r4, [r3, #0xa0]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0xa0]
+
+ /* pll5 disable */
+ ldr r4, [r3, #0xe0]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0xe0]
+
+ /* pll1 disable */
+ ldr r4, [r3, #0x270]
+ bic r4, r4, #0x2000
+ str r4, [r3, #0x270]
+
+ ldr r3, =MVF_CCM_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ ldr r4, [r3, #0x2c]
+ bic r4, r4, #0x100
+ str r4, [r3, #0x2c]
+
+ ldr r3, =MVF_GPC_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ /* enable deep sleep for memories */
+ ldr r4, [r3, #0x0]
+ orr r4, r4, #0x40
+ str r4, [r3, #0x0]
+
+ /* enable LPSTOP3 */
+ ldr r4, [r3, #0x0]
+ bic r4, r4, #0x04
+ bic r4, r4, #0x02
+ str r4, [r3, #0x0]
+
+ /* ensure power domain 1 */
+ ldr r4, [r3, #0x0]
+ orr r4, r4, #0x01
+ str r4, [r3, #0x0]
+
+ /* gpc_lpmr set low-power stop mode */
+ ldr r4, =0x02
+ str r4, [r3, #0x40]
+
+ .endm
+
+/******************************************************************
+Invalidate l1 dcache, r0-r4, r6, r7 used
+******************************************************************/
+ .macro invalidate_l1_dcache
+
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1:
+ sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2:
+ subs r3, r3, #1 @ Temp--
+ mov r7, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r7, r7, r6
+ mcr p15, 0, r7, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+
+ .endm
+
+/******************************************************************
+Flush and disable L1 dcache
+******************************************************************/
+ .macro flush_disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0-r12, lr}
+ ldr r0, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r0
+ pop {r0-r12, lr}
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
+ */
+ push {r0-r12, lr}
+ ldr r0, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r0
+ pop {r0-r12, lr}
+
+ /*
+ * Execute an ISB instruction to ensure that all of the
+ * CP15 register changes have been committed.
+ */
+ isb
+
+ /*
+ * Execute a barrier instruction to ensure that all cache,
+ * TLB and branch predictor maintenance operations issued
+ * by any CPU in the cluster have completed.
+ */
+ dsb
+ dmb
+
+ .endm
+
+ENTRY(mvf_suspend)
+ stmfd sp!, {r0-r12} @ Save registers
+/*************************************************************
+suspend mode entry
+*************************************************************/
+ mov r11, r0
+
+ cmp r0, #0x1
+ bne dormant
+
+ /* Need to flush and disable L1 dcache*/
+ flush_disable_l1_dcache
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+
+ /* Invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0 @ Invalidate I-Cache
+
+ /* Need to invalidate L1 dcache, as the power is dropped */
+ invalidate_l1_dcache
+
+ /* Enable L1 dcache first */
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+
+/***********************************************************
+never run to here
+************************************************************/
+ b out /* exit standby */
+ /* Place the literal pool here so that literals are
+ within 16KB range */
+ .ltorg
+
+/************************************************************
+dormant entry, data save in stack
+************************************************************/
+dormant:
+
+/************************************************************
+saved register and context as below:
+ sp
+ spsr
+ lr
+ CPACR
+ TTBR0
+ TTBR1
+ TTBCR
+ DACR
+ PRRR
+ NMRR
+ ACTLR
+ Context ID
+ User r/w thread ID
+ Secure or NS VBAR
+ CPSR
+ SCTLR
+************************************************************/
+ /* stack is from the tail of iram_suspend base */
+ mov r0, r2 /* get suspend_iram_base */
+ add r0, r0, #IRAM_SUSPEND_SIZE
+
+ mov r4, r11 @ Store state entered
+ stmfd r0!, {r4}
+
+ mov r4, sp @ Store sp
+ mrs r5, spsr @ Store spsr
+ mov r6, lr @ Store lr
+ stmfd r0!, {r4-r6}
+
+ /* c1 and c2 registers */
+ mrc p15, 0, r4, c1, c0, 2 @ CPACR
+ mrc p15, 0, r5, c2, c0, 0 @ TTBR0
+ mrc p15, 0, r6, c2, c0, 1 @ TTBR1
+ mrc p15, 0, r7, c2, c0, 2 @ TTBCR
+ stmfd r0!, {r4-r7}
+
+ /* c3 and c10 registers */
+ mrc p15, 0, r4, c3, c0, 0 @ DACR
+ mrc p15, 0, r5, c10, c2, 0 @ PRRR
+ mrc p15, 0, r6, c10, c2, 1 @ NMRR
+ mrc p15, 0, r7, c1, c0, 1 @ ACTLR
+ stmfd r0!,{r4-r7}
+
+ /* c12, c13 and CPSR registers */
+ mrc p15, 0, r4, c13, c0, 1 @ Context ID
+ mrc p15, 0, r5, c13, c0, 2 @ User r/w thread ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS VBAR
+ mrs r7, cpsr @ Store CPSR
+ stmfd r0!, {r4-r7}
+
+ /* c1 control register */
+ mrc p15, 0, r4, c1, c0, 0 @ SCTLR
+ stmfd r0!, {r4}
+
+ /* Need to flush and disable L1 dcache*/
+ flush_disable_l1_dcache
+
+ /* Make sure TLBs are primed */
+ ldr r1, =MVF_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT_OFFSET
+ add r1, r1, #0x20000
+ ldr r0, [r1]
+ ldr r1, =MVF_SRC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT_OFFSET
+ add r1, r1, #0x20000
+ ldr r0, [r1]
+ ldr r1, =MVF_CCM_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT_OFFSET
+ add r1, r1, #0x20000
+ ldr r0, [r1]
+ ldr r1, =MVF_GPC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT_OFFSET
+ add r1, r1, #0x20000
+ ldr r0, [r1]
+ ldr r1, =MVF_CCM_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT_OFFSET
+ add r1, r1, #0x20000
+ ldr r0, [r1]
+
+ /* Do a DSB to drain the buffers */
+ dsb
+
+ mvf_stop_mode_enter
+
+/****************************************************************
+execute a wfi instruction to let SOC go into stop mode.
+****************************************************************/
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+
+/****************************************************************
+if go here, means there is a wakeup irq pending, we should resume
+system immediately.
+****************************************************************/
+ mov r0, r2 /* get suspend_iram_base */
+ add r0, r0, #IRAM_SUSPEND_SIZE
+
+ ldmea r0!, {r11} @ standby or mem
+
+ /* mask all the GPC interrupts */
+ ldr r3, =MVF_GPC_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+ ldr r4, =0xffffffff
+ str r4, [r3, #0x44]
+ str r4, [r3, #0x48]
+ str r4, [r3, #0x4c]
+ str r4, [r3, #0x50]
+
+ /* pll2 enable */
+ ldr r3, =MVF_ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT_OFFSET
+ add r3, r3, #0x20000
+
+ ldr r4, [r3, #0x30]
+ orr r4, r4, #0x2000
+ str r4, [r3, #0x30]
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mrc p15, 0, r1, c1, c0, 0
+ orr r1, r1, #(1 << 2) @ Enable the C bit
+ mcr p15, 0, r1, c1, c0, 0
+
+ b out
+
+/************************************************
+return back to mvf_suspend_enter for suspend
+*************************************************/
+out:
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+
+ .type mvf_do_suspend, #object
+ENTRY(mvf_do_suspend)
+ .word mvf_suspend
+ .size mvf_suspend, . - mvf_suspend
diff --git a/arch/arm/mach-mvf/pm.c b/arch/arm/mach-mvf/pm.c
new file mode 100644
index 000000000000..0e62caf372da
--- /dev/null
+++ b/arch/arm/mach-mvf/pm.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/iram_alloc.h>
+#include <linux/interrupt.h>
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+#include <mach/mxc_uart.h>
+#include "crm_regs.h"
+#include "regs-anadig.h"
+#include "regs-pm.h"
+#include "regs-src.h"
+
+static struct clk *cpu_clk;
+static struct clk *ipg_clk;
+static struct clk *periph_clk;
+
+extern void mvf_suspend(suspend_state_t state);
+
+static struct device *pm_dev;
+static void __iomem *scu_base;
+static void __iomem *gpc_base;
+static void __iomem *src_base;
+static void __iomem *anadig_base;
+
+static void *suspend_iram_base;
+static void (*suspend_in_iram)(suspend_state_t state,
+ unsigned long iram_paddr, unsigned long suspend_iram_base) = NULL;
+static unsigned long iram_paddr, cpaddr;
+
+static u32 ccm_ccr, ccm_clpcr, ccm_ccsr, scu_ctrl;
+static u32 gpc_imr[4], gpc_pgcr, gpc_lpmr;
+static u32 ccm_anadig_pfd528, ccm_anadig_pfd480_usb0, ccm_anadig_2p5;
+static int g_state;
+
+static void mvf_suspend_store(void)
+{
+ /* save some settings before suspend */
+ ccm_ccr = __raw_readl(MXC_CCM_CCR);
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR);
+ ccm_ccsr = __raw_readl(MXC_CCM_CCSR);
+ ccm_anadig_pfd528 = __raw_readl(PFD_528_BASE_ADDR);
+ ccm_anadig_pfd480_usb0 = __raw_readl(PFD_480_BASE_ADDR);
+ ccm_anadig_2p5 = __raw_readl(ANADIG_2P5_ADDR);
+
+ scu_ctrl = __raw_readl(scu_base + SCU_CTRL_OFFSET);
+ gpc_imr[0] = __raw_readl(gpc_base + GPC_IMR1_OFFSET);
+ gpc_imr[1] = __raw_readl(gpc_base + GPC_IMR2_OFFSET);
+ gpc_imr[2] = __raw_readl(gpc_base + GPC_IMR3_OFFSET);
+ gpc_imr[3] = __raw_readl(gpc_base + GPC_IMR4_OFFSET);
+ gpc_pgcr = __raw_readl(gpc_base + GPC_PGCR_OFFSET);
+ gpc_lpmr = __raw_readl(gpc_base + GPC_LPMR_OFFSET);
+}
+
+static void mvf_suspend_restore(void)
+{
+ /* restore settings after suspend */
+ __raw_writel(ccm_anadig_2p5, ANADIG_2P5_ADDR);
+
+ udelay(50);
+
+ __raw_writel(ccm_ccr, MXC_CCM_CCR);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(ccm_anadig_pfd528, PFD_528_BASE_ADDR);
+ __raw_writel(ccm_anadig_pfd480_usb0, PFD_480_BASE_ADDR);
+
+ __raw_writel(scu_ctrl, scu_base + SCU_CTRL_OFFSET);
+ __raw_writel(gpc_imr[0], gpc_base + GPC_IMR1_OFFSET);
+ __raw_writel(gpc_imr[1], gpc_base + GPC_IMR2_OFFSET);
+ __raw_writel(gpc_imr[2], gpc_base + GPC_IMR3_OFFSET);
+ __raw_writel(gpc_imr[3], gpc_base + GPC_IMR4_OFFSET);
+ __raw_writel(gpc_pgcr, gpc_base + GPC_PGCR_OFFSET);
+ __raw_writel(gpc_lpmr, gpc_base + GPC_LPMR_OFFSET);
+
+ /* enable PLLs */
+ __raw_writel(__raw_readl(PLL3_480_USB1_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL3_480_USB1_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL3_480_USB2_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL3_480_USB2_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL4_AUDIO_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL4_AUDIO_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL6_VIDEO_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL6_VIDEO_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL5_ENET_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL5_ENET_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL1_SYS_BASE_ADDR) | ANADIG_PLL_ENABLE,
+ PLL1_SYS_BASE_ADDR);
+
+ /* restore system clock */
+ __raw_writel(ccm_ccsr, MXC_CCM_CCSR);
+}
+
+static void uart_reinit(unsigned long int clkspeed, unsigned long int baud)
+{
+ void __iomem *membase;
+ u8 tmp;
+ u16 sbr, brfa;
+
+ membase = MVF_IO_ADDRESS(MVF_UART1_BASE_ADDR);
+
+ __raw_writeb(0, membase + MXC_UARTMODEM);
+
+ /* make sure the transmitter and receiver are
+ * disabled while changing settings */
+ tmp = __raw_readb(membase + MXC_UARTCR2);
+ tmp &= ~MXC_UARTCR2_RE;
+ tmp &= ~MXC_UARTCR2_TE;
+ __raw_writeb(tmp, membase + MXC_UARTCR2);
+
+ __raw_writeb(0, membase + MXC_UARTCR1);
+
+ sbr = (u16) ((clkspeed * 1000) / (baud * 16));
+ brfa = ((clkspeed * 1000) / baud) - (sbr * 16);
+
+ tmp = __raw_readb(membase + MXC_UARTBDH);
+ tmp &= ~MXC_UARTBDH_SBR_MASK;
+ tmp |= ((sbr & 0x1f00) >> 8);
+ __raw_writeb(tmp, membase + MXC_UARTBDH);
+ tmp = sbr & 0x00ff;
+ __raw_writeb(tmp, membase + MXC_UARTBDL);
+
+ tmp = __raw_readb(membase + MXC_UARTCR4);
+ tmp &= ~MXC_UARTCR4_BRFA_MASK;
+ tmp |= (brfa & MXC_UARTCR4_BRFA_MASK);
+ __raw_writeb(tmp , membase + MXC_UARTCR4);
+
+ tmp = __raw_readb(membase + MXC_UARTCR2);
+ tmp |= MXC_UARTCR2_RE;
+ tmp |= MXC_UARTCR2_TE;
+ __raw_writeb(tmp, membase + MXC_UARTCR2);
+}
+
+static int mvf_suspend_enter(suspend_state_t state)
+{
+ struct gic_dist_state gds;
+ struct gic_cpu_state gcs;
+ bool arm_pg = false;
+
+ mvf_suspend_store();
+
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mvf_cpu_lp_set(LOW_POWER_STOP);
+ g_state = PM_SUSPEND_MEM;
+ arm_pg = true;
+ break;
+ case PM_SUSPEND_STANDBY:
+ mvf_cpu_lp_set(LOW_POWER_RUN);
+ g_state = PM_SUSPEND_STANDBY;
+ arm_pg = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) {
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ if (arm_pg) {
+ /* preserve GIC state */
+ save_gic_dist_state(0, &gds);
+ save_gic_cpu_state(0, &gcs);
+ }
+
+ suspend_in_iram(state, (unsigned long)iram_paddr,
+ (unsigned long)suspend_iram_base);
+
+ /* reconfigure UART1 when using 24MHz system clock */
+ uart_reinit(4000, 115200);
+
+ printk(KERN_DEBUG "Read GPC_PGSR register: %x\n",
+ __raw_readl(gpc_base + GPC_PGSR_OFFSET));
+
+ /* mask all interrupts */
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR1_OFFSET);
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR2_OFFSET);
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR3_OFFSET);
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR4_OFFSET);
+
+ udelay(80);
+
+ if (arm_pg) {
+ /* restore GIC registers */
+ restore_gic_dist_state(0, &gds);
+ restore_gic_cpu_state(0, &gcs);
+ }
+
+ mvf_suspend_restore();
+
+ /* reconfigure UART1 when using 396MHz system clock */
+ uart_reinit(66000, 115200);
+
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ ANADIG_MISC0_REG);
+ } else
+ cpu_do_idle();
+
+ return 0;
+}
+
+static void mvf_suspend_finish(void)
+{
+ if (g_state == PM_SUSPEND_MEM)
+ free_irq(MVF_INT_WKPU0, NULL);
+}
+
+static int mvf_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+const struct platform_suspend_ops mvf_suspend_ops = {
+ .valid = mvf_pm_valid,
+ .enter = mvf_suspend_enter,
+ .finish = mvf_suspend_finish,
+};
+
+static int __devinit mvf_pm_probe(struct platform_device *pdev)
+{
+ pm_dev = &pdev->dev;
+
+ return 0;
+}
+
+static struct platform_driver mvf_pm_driver = {
+ .driver = {
+ .name = "imx_pm",
+ },
+ .probe = mvf_pm_probe,
+};
+
+static int __init pm_init(void)
+{
+ scu_base = MVF_IO_ADDRESS(MVF_SCUGIC_BASE_ADDR);
+ gpc_base = MVF_GPC_BASE;
+ anadig_base = MXC_PLL_BASE;
+ src_base = MVF_IO_ADDRESS(MVF_SRC_BASE_ADDR);
+
+ pr_info("Static Power Management for Freescale Vybrid\n");
+
+ if (platform_driver_register(&mvf_pm_driver) != 0) {
+ printk(KERN_ERR "mvf_pm_driver register failed\n");
+ return -ENODEV;
+ }
+
+ suspend_set_ops(&mvf_suspend_ops);
+
+ /* move suspend routine into sram */
+ cpaddr = (unsigned long)iram_alloc(SZ_32K, &iram_paddr);
+
+ /* need to remap the area here since we want the memory region
+ * to be executable */
+ suspend_iram_base = __arm_ioremap(iram_paddr, SZ_32K,
+ MT_MEMORY_NONCACHED);
+ printk(KERN_DEBUG "cpaddr = %x suspend_iram_base=%x iram_paddr %x\n",
+ (unsigned int)cpaddr, (unsigned int)suspend_iram_base,
+ (unsigned int)iram_paddr);
+
+ /* need to run the suspend code from sram */
+ memcpy((void *)cpaddr, mvf_suspend, SZ_32K);
+
+ suspend_in_iram = (void *)suspend_iram_base;
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+ ipg_clk = clk_get(NULL, "ipg_clk");
+ if (IS_ERR(ipg_clk)) {
+ printk(KERN_DEBUG "%s: failed to get ipg_clk\n", __func__);
+ return PTR_ERR(ipg_clk);
+ }
+ periph_clk = clk_get(NULL, "periph_clk");
+ if (IS_ERR(periph_clk)) {
+ printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__);
+ return PTR_ERR(periph_clk);
+ }
+
+ printk(KERN_INFO "PM driver module loaded\n");
+ return 0;
+}
+
+static void __exit pm_cleanup(void)
+{
+ platform_driver_unregister(&mvf_pm_driver);
+}
+
+module_init(pm_init);
+module_exit(pm_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("PM driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mvf/regs-pm.h b/arch/arm/mach-mvf/regs-pm.h
new file mode 100644
index 000000000000..c54bdd346709
--- /dev/null
+++ b/arch/arm/mach-mvf/regs-pm.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * This 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MVF_REGS_PM_H__
+#define __ARCH_ARM_MACH_MVF_REGS_PM_H__
+
+/* GPC registers */
+#define GPC_PGCR_OFFSET (0x00)
+#define GPC_PGCR_DS_STOP (0x000000080)
+#define GPC_PGCR_DS_LPSTOP (0x000000040)
+#define GPC_PGCR_WB_STOP (0x000000010)
+#define GPC_PGCR_HP_OFF (0x000000008)
+#define GPC_PGCR_PG_48K (0x000000004)
+#define GPC_PGCR_PG_16K (0x000000002)
+#define GPC_PGCR_PG_PD1 (0x000000001)
+
+#define GPC_PGSR_OFFSET (0x0c)
+
+#define GPC_LPMR_OFFSET (0x40)
+#define GPC_LPMR_CLPCR_RUN (0x00000000)
+#define GPC_LPMR_CLPCR_WAIT (0x00000001)
+#define GPC_LPMR_CLPCR_STOP (0x00000002)
+
+#define GPC_IMR1_OFFSET (0x44)
+#define GPC_IMR2_OFFSET (0x48)
+#define GPC_IMR3_OFFSET (0x4c)
+#define GPC_IMR4_OFFSET (0x50)
+#define GPC_ISR1_OFFSET (0x54)
+#define GPC_ISR2_OFFSET (0x58)
+#define GPC_ISR3_OFFSET (0x5c)
+#define GPC_ISR4_OFFSET (0x60)
+
+/* VREG registers */
+#define VREG_CTRL_OFFSET (0x00)
+#define VREG_CTRL_PORPU (0x00010000)
+#define VREG_CTRL_HVDMASK (0x00000001)
+#define VREG_STAT_OFFSET (0x04)
+
+/* WKPU registers */
+#define WKPU_NSR_OFFSET (0x00)
+
+#define WKPU_NCR_OFFSET (0x08)
+#define WKPU_NCR_NLOCK0 (0x80000000)
+#define WKPU_NCR_NWRE0 (0x10000000)
+#define WKPU_NCR_NREE0 (0x04000000)
+#define WKPU_NCR_NFEE0 (0x02000000)
+#define WKPU_NCR_NFE0 (0x01000000)
+
+#define WKPU_WISR_OFFSET (0x14)
+
+#define WKPU_IRER_OFFSET (0x18)
+
+#define WKPU_WRER_OFFSET (0x1c)
+
+#define WKPU_WIREER_OFFSET (0x28)
+
+#define WKPU_WIFEER_OFFSET (0x2c)
+
+#define WKPU_WIFER_OFFSET (0x30)
+
+#define WKPU_WIPUER_OFFSET (0x34)
+
+#define RISING_EDGE_ENABLED (0x9e)
+#define FALLING_EDGE_ENABLED (0xfe)
+
+/* SCU registers */
+#define SCU_CTRL_OFFSET (0x00)
+
+
+#endif /* __ARCH_ARM_MACH_MVF_REGS_PM_H__ */
diff --git a/arch/arm/mach-mvf/regs-src.h b/arch/arm/mach-mvf/regs-src.h
new file mode 100644
index 000000000000..b93e99d92da1
--- /dev/null
+++ b/arch/arm/mach-mvf/regs-src.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _SRC_REGISTER_HEADER_
+#define _SRC_REGISTER_HEADER_
+
+#define SRC_SCR_OFFSET 0x000
+#define SRC_SBMR_OFFSET 0x004
+#define SRC_SRSR_OFFSET 0x008
+#define SRC_SECR_OFFSET 0x00c
+#define SRC_SISR_OFFSET 0x014
+#define SRC_SIMR_OFFSET 0x018
+#define SRC_SBMR2_OFFSET 0x01c
+#define SRC_GPR0_OFFSET 0x020
+#define SRC_GPR1_OFFSET 0x024
+#define SRC_GPR2_OFFSET 0x028
+#define SRC_GPR3_OFFSET 0x02c
+#define SRC_GPR4_OFFSET 0x030
+#define SRC_HAB0_OFFSET 0x034
+#define SRC_HAB1_OFFSET 0x038
+#define SRC_HAB2_OFFSET 0x03c
+#define SRC_HAB3_OFFSET 0x040
+#define SRC_HAB4_OFFSET 0x044
+#define SRC_HAB5_OFFSET 0x048
+#define SRC_MISC0_OFFSET 0x04c
+#define SRC_MISC1_OFFSET 0x050
+#define SRC_MISC2_OFFSET 0x054
+#define SRC_MISC3_OFFSET 0x058
+
+#endif
diff --git a/arch/arm/mach-mvf/system.c b/arch/arm/mach-mvf/system.c
index 764c608cbf42..989c75a02ed1 100644
--- a/arch/arm/mach-mvf/system.c
+++ b/arch/arm/mach-mvf/system.c
@@ -21,7 +21,8 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
-#include <linux/pmic_external.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
#include <asm/io.h>
#include <mach/hardware.h>
#include <mach/clock.h>
@@ -29,6 +30,142 @@
#include <asm/system.h>
#include "crm_regs.h"
#include "regs-anadig.h"
+#include "regs-pm.h"
+
+#define SW1_WAKEUP_PIN 38
+#define SW1_PORT1_PCR6_ADDR 0x4004a018
+
+static void __iomem *gpc_base = MVF_GPC_BASE;
+
+void gpc_set_wakeup(void)
+{
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR1_OFFSET);
+ __raw_writel(0xffffffff, gpc_base + GPC_IMR2_OFFSET);
+ /* unmask WKPU0 interrupt */
+ __raw_writel(0xefffffff, gpc_base + GPC_IMR3_OFFSET);
+ /* unmask GPIO4 interrupt */
+ __raw_writel(0xffff7fff, gpc_base + GPC_IMR4_OFFSET);
+
+ return;
+}
+
+void enable_wkpu(u32 source, u32 rise_fall)
+{
+ __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_IRER_OFFSET);
+ __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WRER_OFFSET);
+
+ if (rise_fall == RISING_EDGE_ENABLED)
+ __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WIREER_OFFSET);
+ else
+ __raw_writel(1 << source, MVF_WKPU_BASE + WKPU_WIFEER_OFFSET);
+}
+
+static irqreturn_t wkpu_irq(int irq, void *dev_id)
+{
+ u32 wisr;
+
+ wisr = __raw_readl(MVF_WKPU_BASE + WKPU_WISR_OFFSET);
+ if (wisr)
+ __raw_writel(wisr, MVF_WKPU_BASE + WKPU_WISR_OFFSET);
+
+ return IRQ_NONE;
+}
+
+/* set cpu multiple modes before WFI instruction */
+void mvf_cpu_lp_set(enum mvf_cpu_pwr_mode mode)
+{
+ u32 ccm_ccsr, ccm_clpcr, ccm_ccr;
+ u32 tmp;
+ int ret;
+
+ if ((mode == LOW_POWER_STOP) || (mode == STOP_MODE)) {
+ /* config SW1 for waking up system */
+ gpio_request_one(SW1_WAKEUP_PIN, GPIOF_IN, "SW1 wakeup");
+ gpio_set_value(SW1_WAKEUP_PIN, 0);
+ /* PORT1_PCR6 IRQC interrupt/dma request disabled */
+ tmp = __raw_readl(MVF_IO_ADDRESS(SW1_PORT1_PCR6_ADDR));
+ tmp &= ~0x000f0000;
+ __raw_writel(tmp, MVF_IO_ADDRESS(SW1_PORT1_PCR6_ADDR));
+
+ ret = request_irq(MVF_INT_WKPU0, wkpu_irq,
+ IRQF_DISABLED, "wkpu irq", NULL);
+ if (ret)
+ printk(KERN_ERR "Request wkpu IRQ failed\n");
+
+ /* enable WKPU interrupt */
+ enable_wkpu(11, FALLING_EDGE_ENABLED);
+ }
+
+ ccm_ccr = __raw_readl(MXC_CCM_CCR);
+ ccm_ccsr = __raw_readl(MXC_CCM_CCSR);
+
+ switch (mode) {
+ case WAIT_MODE:
+ break;
+ case LOW_POWER_RUN:
+ ccm_ccr |= MXC_CCM_CCR_FIRC_EN;
+ __raw_writel(ccm_ccr, MXC_CCM_CCR);
+ ccm_ccsr &= ~MXC_CCM_CCSR_FAST_CLK_SEL_MASK;
+ ccm_ccsr &= ~MXC_CCM_CCSR_SLOW_CLK_SEL_MASK;
+ __raw_writel(ccm_ccsr, MXC_CCM_CCSR);
+
+ /* switch system clock to FIRC 24MHz */
+ ccm_ccsr &= ~MXC_CCM_CCSR_SYS_CLK_SEL_MASK;
+ __raw_writel(ccm_ccsr, MXC_CCM_CCSR);
+
+ __raw_writel(__raw_readl(PLL3_480_USB1_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL3_480_USB1_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL3_480_USB2_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL3_480_USB2_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL4_AUDIO_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL4_AUDIO_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL6_VIDEO_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL6_VIDEO_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL5_ENET_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL5_ENET_BASE_ADDR);
+ __raw_writel(__raw_readl(PLL1_SYS_BASE_ADDR) &
+ ~ANADIG_PLL_ENABLE, PLL1_SYS_BASE_ADDR);
+ break;
+ case STOP_MODE:
+ case LOW_POWER_STOP:
+ gpc_set_wakeup();
+
+ /* unmask UART1 in low-power mode */
+ __raw_writel(0xfffeffff, MXC_CCM_CCGR0);
+ /* unmask WKUP and GPC in low-power mode */
+ __raw_writel(0xfeefffff, MXC_CCM_CCGR4);
+ /* unmask DDRC in low-power mode */
+ __raw_writel(0xefffffff, MXC_CCM_CCGR6);
+
+ ccm_ccr |= MXC_CCM_CCR_FIRC_EN;
+ __raw_writel(ccm_ccr, MXC_CCM_CCR);
+ ccm_ccsr &= ~MXC_CCM_CCSR_FAST_CLK_SEL_MASK;
+ ccm_ccsr &= ~MXC_CCM_CCSR_SLOW_CLK_SEL_MASK;
+ __raw_writel(ccm_ccsr, MXC_CCM_CCSR);
+
+ /* switch system clock to FIRC 24MHz */
+ ccm_ccsr &= ~MXC_CCM_CCSR_SYS_CLK_SEL_MASK;
+ __raw_writel(ccm_ccsr, MXC_CCM_CCSR);
+
+ /* on-chip oscillator will not be
+ * powered down in stop mode */
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR);
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_M_CORE1_WFI;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_M_CORE0_WFI;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_ARM_CLK_LPM;
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+
+ /* mask stop mode to Anatop */
+ __raw_writel(ccm_clpcr & ~MXC_CCM_CLPCR_ANATOP_STOP_MODE,
+ MXC_CCM_CLPCR);
+
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOW cpu power mode: %d\n", mode);
+ return;
+ }
+}
void arch_idle(void)
{
diff --git a/arch/arm/mach-mvf/usb_dr.c b/arch/arm/mach-mvf/usb_dr.c
index 2467acc1bf28..34377c4c19b3 100644
--- a/arch/arm/mach-mvf/usb_dr.c
+++ b/arch/arm/mach-mvf/usb_dr.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
#include <linux/fsl_devices.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -35,11 +36,8 @@ static int usbotg_init_ext(struct platform_device *pdev);
static void usbotg_uninit_ext(struct platform_device *pdev);
static void usbotg_clock_gate(bool on);
static void _dr_discharge_line(bool enable);
+static void usbotg_wakeup_event_clear(void);
-/* The usb_phy0_clk do not have enable/disable function at clock.c
- * and PLL output for usb0's phy should be always enabled.
- * usb_phy0_clk only stands for usb uses pll3 as its parent.
- */
static struct clk *usb_phy0_clk;
static u8 otg_used;
@@ -62,19 +60,24 @@ static struct fsl_usb2_platform_data dr_utmi_config = {
.dr_discharge_line = _dr_discharge_line,
};
+/* Platform data for wakeup operation */
+static struct fsl_usb2_wakeup_platform_data dr_wakeup_config = {
+ .name = "Host wakeup",
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .usb_wakeup_exhandle = usbotg_wakeup_event_clear,
+};
+
static void usbotg_internal_phy_clock_gate(bool on)
{
- u32 reg;
-
void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
- reg = __raw_readl(phy_reg + HW_USBPHY_CTRL);
if (on)
- reg &= ~BM_USBPHY_CTRL_CLKGATE;
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE,
+ phy_reg + HW_USBPHY_CTRL_CLR);
else
- reg |= BM_USBPHY_CTRL_CLKGATE;
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE,
+ phy_reg + HW_USBPHY_CTRL_SET);
- __raw_writel(reg, phy_reg + HW_USBPHY_CTRL);
}
static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
@@ -106,6 +109,13 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
/* Power up the PHY */
__raw_writel(0, phy_reg + HW_USBPHY_PWD);
+ if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
+ (pdata->operating_mode == FSL_USB2_DR_OTG)) {
+ /* enable FS/LS device */
+ __raw_writel(
+ BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3,
+ phy_reg + HW_USBPHY_CTRL_SET);
+ }
return 0;
}
@@ -128,8 +138,8 @@ static int usbotg_init_ext(struct platform_device *pdev)
usbotg_internal_phy_clock_gate(true);
usb_phy_enable(pdev->dev.platform_data);
/*
- * after the phy reset,can not read the value for id/vbus at
- * the register of otgsc ,cannot read at once ,need delay 3 ms
+ * after the phy reset,can't read the value for id/vbus at
+ * the register of otgsc at once ,need delay 3 ms
*/
mdelay(3);
}
@@ -151,21 +161,18 @@ static void usbotg_uninit_ext(struct platform_device *pdev)
static void usbotg_clock_gate(bool on)
{
- pr_debug("%s: on is %d\n", __func__, on);
+
if (on)
clk_enable(usb_phy0_clk);
else
clk_disable(usb_phy0_clk);
+
}
-/*
-void mvf_set_otghost_vbus_func(driver_vbus_func driver_vbus)
-{
- dr_utmi_config.platform_driver_vbus = driver_vbus;
-}
-*/
+
static void _dr_discharge_line(bool enable)
{
void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
+
if (enable) {
__raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x3),
phy_reg + HW_USBPHY_DEBUG_SET);
@@ -183,48 +190,275 @@ static void _dr_discharge_line(bool enable)
/* Below two macros are used at otg mode to indicate usb mode*/
#define ENABLED_BY_HOST (0x1 << 0)
#define ENABLED_BY_DEVICE (0x1 << 1)
+static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
+ u32 tmp;
+ pr_debug("DR: %s begins, enable is %d\n", __func__, enable);
+
+ if (enable) {
+ UOG_PORTSC1 |= PORTSC_PHCD;
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+ usbotg_internal_phy_clock_gate(false);
+
+ } else {
+ if (UOG_PORTSC1 & PORTSC_PHCD) {
+ UOG_PORTSC1 &= ~PORTSC_PHCD;
+ mdelay(1);
+ }
+ usbotg_internal_phy_clock_gate(true);
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ }
+ pr_debug("DR: %s ends, enable is %d\n", __func__, enable);
+}
+
+static void __phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable, int source)
+{
+ if (enable)
+ enter_phy_lowpower_suspend(pdata, enable);
+ else {
+ pr_debug("phy lowpower disable\n");
+ enter_phy_lowpower_suspend(pdata, enable);
+ }
+}
+
+static void otg_wake_up_enable(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
+
+ pr_debug("%s, enable is %d\n", __func__, enable);
+ if (enable) {
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP
+ | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
+ | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL,
+ phy_reg + HW_USBPHY_CTRL_SET);
+ USBC0_CTRL |= UCTRL_OWIE;
+ } else {
+ USBC0_CTRL &= ~UCTRL_OWIE;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void __wakeup_irq_enable(struct fsl_usb2_platform_data *pdata,
+ bool on, int source)
+{
+ pr_debug("USB Host %s,on=%d\n", __func__, on);
+ mdelay(3);
+ if (on) {
+ otg_wake_up_enable(pdata, on);
+ } else {
+ otg_wake_up_enable(pdata, on);
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+/* The wakeup operation for DR port, it will clear the wakeup irq status
+ * and re-enable the wakeup
+ */
+static void usbotg_wakeup_event_clear(void)
+{
+ int wakeup_req = USBC0_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req != 0) {
+ pr_debug("Unknown wakeup.(OTGSC 0x%x)\n", UOG_OTGSC);
+ /* Disable OWIE to clear OWIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USBC0_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USBC0_CTRL |= UCTRL_OWIE;
+ }
+}
+
+/* End of Common operation for DR port */
#ifdef CONFIG_USB_EHCI_ARC_OTG
-#endif /* CONFIG_USB_EHCI_ARC_OTG */
+/* Beginning of host related operation for DR port */
+static void _host_platform_suspend(struct fsl_usb2_platform_data *pdata)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
+ u32 tmp;
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+}
-#ifdef CONFIG_USB_GADGET_ARC
-#endif /* CONFIG_USB_GADGET_ARC */
+static void _host_platform_resume(struct fsl_usb2_platform_data *pdata)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY0_BASE_ADDR);
+ u32 tmp;
-void __init mvf_usb_dr_init(void)
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+}
+
+static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable)
{
- struct platform_device *pdev;
- u32 reg;
-#ifdef CONFIG_USB_GADGET_ARC
- dr_utmi_config.operating_mode = DR_UDC_MODE;
- dr_utmi_config.platform_suspend = NULL;
- dr_utmi_config.platform_resume = NULL;
+ __phy_lowpower_suspend(pdata, enable, ENABLED_BY_HOST);
+}
- pdev = mvf_add_fsl_usb2_udc(&dr_utmi_config);
+static void _host_wakeup_enable(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ __wakeup_irq_enable(pdata, enable, ENABLED_BY_HOST);
- __raw_writel(((0x01 << 30) | 0x2), ANADIG_USB1_MISC);
+ if (enable)
+ device_wakeup_enable(&pdata->pdev->dev);
+ else
+ device_wakeup_disable(&pdata->pdev->dev);
+}
- __raw_writel(0x00000894, USBPHY1_CTRL);
- udelay(10);
+static enum usb_wakeup_event
+_is_host_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USBC0_CTRL & UCTRL_OWIR;
+ u32 otgsc = UOG_OTGSC;
- __raw_writel(0x0, USBPHY1_PWD);
- __raw_writel(0x1, USBPHY1_IP);
+ if (wakeup_req) {
+ pr_debug("the otgsc is 0x%x, usbsts is 0x%x,"
+ " portsc is 0x%x, wakeup_irq is 0x%x\n",
+ UOG_OTGSC, UOG_USBSTS, UOG_PORTSC1, wakeup_req);
+ }
+ /* if ID change sts, it is a host wakeup event */
+ if (wakeup_req && (otgsc & OTGSC_IS_USB_ID)) {
+ pr_debug("otg host ID wakeup\n");
+ /* if host ID wakeup, we must clear the b session change sts */
+ otgsc &= (~OTGSC_IS_USB_ID);
+ return WAKEUP_EVENT_ID;
+ }
+ if (wakeup_req && (!(otgsc & OTGSC_STS_USB_ID))) {
+ pr_debug("otg host Remote wakeup\n");
+ return WAKEUP_EVENT_DPDM;
+ }
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _host_phy_lowpower_suspend(pdata, false);
+ _host_wakeup_enable(pdata, false);
+}
+
+/* End of host related operation for DR port */
+#endif /* CONFIG_USB_EHCI_ARC_OTG */
+
+
+void __init mvf_usb_dr_init(void)
+{
+ struct platform_device *pdev, *pdev_wakeup;
+ u32 reg;
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ dr_utmi_config.operating_mode = DR_HOST_MODE;
+ dr_utmi_config.wake_up_enable = _host_wakeup_enable;
+ dr_utmi_config.platform_suspend = _host_platform_suspend;
+ dr_utmi_config.platform_resume = _host_platform_resume;
+ dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_host_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = host_wakeup_handler;
+
+ pdev = mvf_add_fsl_ehci_otg(0, &dr_utmi_config);
+
+ dr_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
+
+ /* register wakeup device */
+ pdev_wakeup = mvf_add_fsl_usb2_ehci_otg_wakeup(0, &dr_wakeup_config);
+ if (pdev != NULL)
+ ((struct fsl_usb2_platform_data *)
+ (pdev->dev.platform_data))->wakeup_pdata =
+ (struct fsl_usb2_wakeup_platform_data *)
+ (pdev_wakeup->dev.platform_data);
+
+ __raw_writel(0x0220C802, USBPHY1_CTRL);
udelay(20);
- __raw_writel(0x7, USBPHY1_IP);
+
+ __raw_writel(0x0, USBPHY1_PWD);
reg = __raw_readl(USBPHY1_DEBUG);
- reg &= ~0x40000000; /* clear gate clock */
+ reg &= ~0x40000000; /* clear clock gate */
__raw_writel(reg, USBPHY1_DEBUG);
+ reg = __raw_readl(ANADIG_USB1_MISC);
+ reg |= (0x01 << 30); /* Enable CLK_TO_UTMI */
+ __raw_writel(reg, ANADIG_USB1_MISC);
+
__raw_writel(0x10000007, USBPHY1_TX);
+ /*__raw_writel(0x100F0F07, USBPHY1_TX);*/
+
+ /* Enable disconnect detect */
reg = __raw_readl(USBPHY1_CTRL);
- reg |= ((0xD1 << 11) | 0x6);
+ reg &= ~0x040; /* clear OTG ID change IRQ */
+ reg |= (0x1 << 14); /* Enable UTMI+ level2 */
+ reg |= (0x1 << 9);
+ reg |= (0x1 << 15); /* Enable UTMI+ level3 */
+ reg &= ~((0xD1 << 11) | 0x6);
__raw_writel(reg, USBPHY1_CTRL);
+ __raw_writel(0x1 << 3, USBPHY1_CTRL + 0x8);
+ /* Disable VBUS and CHARGER detect */
reg = __raw_readl(ANADIG_USB1_VBUS_DETECT);
reg |= 0xE8;
__raw_writel(reg, ANADIG_USB1_VBUS_DETECT);
__raw_writel(0x001c0000, ANADIG_USB1_CHRG_DETECT);
+
#endif
+}
+
+/* USB HIGH_SPEED disconnect detect on/off */
+void fsl_platform_set_usb0_phy_dis(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ u32 reg;
+ reg = __raw_readl(USBPHY1_CTRL);
+
+ if (enable)
+ reg |= ((0xD1 << 11) | 0x6);
+ else
+ reg &= ~((0xD1 << 11) | 0x6);
+
+ __raw_writel(reg, USBPHY1_CTRL);
+
+ __raw_writel(0x1 << 3, USBPHY1_CTRL + 0x8);
}
diff --git a/arch/arm/mach-mvf/usb_dr2.c b/arch/arm/mach-mvf/usb_dr2.c
index d26cfde125e0..c1d6ebf51791 100644
--- a/arch/arm/mach-mvf/usb_dr2.c
+++ b/arch/arm/mach-mvf/usb_dr2.c
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeup.h>
#include <linux/fsl_devices.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -31,10 +32,11 @@
#include "regs-anadig.h"
#include "usb.h"
-static int usbotg2_init_ext(struct platform_device *pdev);
-static void usbotg2_uninit_ext(struct platform_device *pdev);
+static int usbotg_init_ext(struct platform_device *pdev);
+static void usbotg_uninit_ext(struct platform_device *pdev);
static void usbotg_clock_gate(bool on);
static void _dr_discharge_line(bool enable);
+static void usbotg_wakeup_event_clear(void);
static struct clk *usb_phy1_clk;
static u8 otg2_used;
@@ -47,9 +49,9 @@ static u8 otg2_used;
* - operating_mode plugged at run time
*/
static struct fsl_usb2_platform_data dr_utmi_config = {
- .name = "DR",
- .init = usbotg2_init_ext,
- .exit = usbotg2_uninit_ext,
+ .name = "DR2",
+ .init = usbotg_init_ext,
+ .exit = usbotg_uninit_ext,
.phy_mode = FSL_USB2_PHY_UTMI_WIDE,
.power_budget = 500, /* 500 mA max power */
.usb_clock_for_pm = usbotg_clock_gate,
@@ -58,6 +60,13 @@ static struct fsl_usb2_platform_data dr_utmi_config = {
.dr_discharge_line = _dr_discharge_line,
};
+/* Platform data for wakeup operation */
+static struct fsl_usb2_wakeup_platform_data dr_wakeup_config = {
+ .name = "Host wakeup",
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .usb_wakeup_exhandle = usbotg_wakeup_event_clear,
+};
+
static void usbotg_internal_phy_clock_gate(bool on)
{
void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY1_BASE_ADDR);
@@ -111,7 +120,7 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
return 0;
}
/* Notes: configure USB clock*/
-static int usbotg2_init_ext(struct platform_device *pdev)
+static int usbotg_init_ext(struct platform_device *pdev)
{
struct clk *usb_clk;
u32 ret;
@@ -139,7 +148,7 @@ static int usbotg2_init_ext(struct platform_device *pdev)
return ret;
}
-static void usbotg2_uninit_ext(struct platform_device *pdev)
+static void usbotg_uninit_ext(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
@@ -181,6 +190,113 @@ static void _dr_discharge_line(bool enable)
/* Below two macros are used at otg mode to indicate usb mode*/
#define ENABLED_BY_HOST (0x1 << 0)
#define ENABLED_BY_DEVICE (0x1 << 1)
+static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY1_BASE_ADDR);
+ u32 tmp;
+ pr_debug("DR: %s begins, enable is %d\n", __func__, enable);
+
+ if (enable) {
+ UOG2_PORTSC1 |= PORTSC_PHCD;
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+ usbotg_internal_phy_clock_gate(false);
+
+ } else {
+ if (UOG2_PORTSC1 & PORTSC_PHCD) {
+ UOG2_PORTSC1 &= ~PORTSC_PHCD;
+ mdelay(1);
+ }
+ usbotg_internal_phy_clock_gate(true);
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ }
+ pr_debug("DR: %s ends, enable is %d\n", __func__, enable);
+}
+
+static void __phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable, int source)
+{
+ if (enable)
+ enter_phy_lowpower_suspend(pdata, enable);
+ else {
+ pr_debug("phy lowpower disable\n");
+ enter_phy_lowpower_suspend(pdata, enable);
+ }
+}
+
+static void otg_wake_up_enable(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ void __iomem *phy_reg = MVF_IO_ADDRESS(MVF_USBPHY1_BASE_ADDR);
+
+ pr_debug("%s, enable is %d\n", __func__, enable);
+ if (enable) {
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP
+ | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
+ | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL,
+ phy_reg + HW_USBPHY_CTRL_SET);
+ USBC1_CTRL |= UCTRL_OWIE;
+ } else {
+ USBC1_CTRL &= ~UCTRL_OWIE;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void __wakeup_irq_enable(struct fsl_usb2_platform_data *pdata,
+ bool on, int source)
+{
+ pr_debug("USB Host %s,on=%d\n", __func__, on);
+ mdelay(3);
+ if (on) {
+ otg_wake_up_enable(pdata, on);
+ } else {
+ otg_wake_up_enable(pdata, on);
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+/* The wakeup operation for DR port, it will clear the wakeup irq status
+ * and re-enable the wakeup
+ */
+static void usbotg_wakeup_event_clear(void)
+{
+ int wakeup_req = USBC1_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req != 0) {
+ pr_debug("Unknown wakeup.(OTGSC 0x%x)\n", UOG2_OTGSC);
+ /* Disable OWIE to clear OWIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USBC1_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USBC1_CTRL |= UCTRL_OWIE;
+ }
+}
+
/* End of Common operation for DR port */
#ifdef CONFIG_USB_EHCI_ARC_OTG
@@ -215,21 +331,84 @@ static void _host_platform_resume(struct fsl_usb2_platform_data *pdata)
__raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
}
+static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ __phy_lowpower_suspend(pdata, enable, ENABLED_BY_HOST);
+}
+
+static void _host_wakeup_enable(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ __wakeup_irq_enable(pdata, enable, ENABLED_BY_HOST);
+
+ if (enable)
+ device_wakeup_enable(&pdata->pdev->dev);
+ else
+ device_wakeup_disable(&pdata->pdev->dev);
+}
+
+static enum usb_wakeup_event
+_is_host_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USBC1_CTRL & UCTRL_OWIR;
+ u32 otgsc = UOG2_OTGSC;
+
+ if (wakeup_req) {
+ pr_debug("the otgsc is 0x%x, usbsts is 0x%x,"
+ " portsc is 0x%x, wakeup_irq is 0x%x\n",
+ UOG2_OTGSC, UOG2_USBSTS, UOG2_PORTSC1, wakeup_req);
+ }
+ /* if ID change sts, it is a host wakeup event */
+ if (wakeup_req && (otgsc & OTGSC_IS_USB_ID)) {
+ pr_debug("otg host ID wakeup\n");
+ /* if host ID wakeup, we must clear the b session change sts */
+ otgsc &= (~OTGSC_IS_USB_ID);
+ return WAKEUP_EVENT_ID;
+ }
+ if (wakeup_req && (!(otgsc & OTGSC_STS_USB_ID))) {
+ pr_debug("otg host Remote wakeup\n");
+ return WAKEUP_EVENT_DPDM;
+ }
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _host_phy_lowpower_suspend(pdata, false);
+ _host_wakeup_enable(pdata, false);
+}
+
/* End of host related operation for DR port */
#endif /* CONFIG_USB_EHCI_ARC_OTG */
void __init mvf_usb_dr2_init(void)
{
- struct platform_device *pdev;
+ struct platform_device *pdev, *pdev_wakeup;
u32 reg;
#ifdef CONFIG_USB_EHCI_ARC_OTG
dr_utmi_config.operating_mode = DR_HOST_MODE;
+ dr_utmi_config.wake_up_enable = _host_wakeup_enable;
dr_utmi_config.platform_suspend = _host_platform_suspend;
dr_utmi_config.platform_resume = _host_platform_resume;
+ dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_host_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = host_wakeup_handler;
+
+ pdev = mvf_add_fsl_ehci_otg(1, &dr_utmi_config);
+
+ dr_wakeup_config.usb_pdata[1] = pdev->dev.platform_data;
- pdev = mvf_add_fsl_ehci_otg(&dr_utmi_config);
+ /* register wakeup device */
+ pdev_wakeup = mvf_add_fsl_usb2_ehci_otg_wakeup(1, &dr_wakeup_config);
+ if (pdev != NULL)
+ ((struct fsl_usb2_platform_data *)
+ (pdev->dev.platform_data))->wakeup_pdata =
+ (struct fsl_usb2_wakeup_platform_data *)
+ (pdev_wakeup->dev.platform_data);
__raw_writel(0x0220C802, USBPHY2_CTRL);
udelay(20);
@@ -267,7 +446,7 @@ void __init mvf_usb_dr2_init(void)
}
/* USB HIGH_SPEED disconnect detect on/off */
-void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata,
+void fsl_platform_set_usb1_phy_dis(struct fsl_usb2_platform_data *pdata,
bool enable)
{
u32 reg;
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index de80caba49c3..42a52220383e 100755
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -28,6 +28,10 @@ config IMX_HAVE_PLATFORM_IMX21_HCD
config IMX_HAVE_PLATFORM_IMX2_WDT
bool
+config IMX_HAVE_PLATFORM_MVF_ADC
+ bool
+ default y if ARCH_MVF
+
config IMX_HAVE_PLATFORM_IMXDI_RTC
bool
@@ -37,6 +41,10 @@ config IMX_HAVE_PLATFORM_IMX_SRTC
config IMX_HAVE_PLATFORM_IMX_SNVS_RTC
bool
+config IMX_HAVE_PLATFORM_MVF_CAAM
+ bool
+ default y if SOC_MVFA5
+
config IMX_HAVE_PLATFORM_IMX_FB
bool
select HAVE_FB_IMX
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 63be99251f08..807de8385db0 100755
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -62,5 +62,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC) += platform-imx-asrc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI) += platform-imx-mipi_dsi.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2) += platform-imx-mipi_csi2.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MVF_SPI) += platform-mvf-spi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MVF_ADC) += platform-mvf-adc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MVF_DCU) += platform-mvf-dcu.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_MVF_SAI) += platform-mvf-sai.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MVF_CAAM) += platform-mvf-caam.o
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
index d50c5b0be550..5d7605421294 100644
--- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
@@ -18,6 +18,12 @@
.irq = soc ## _INT_USB_OTG, \
}
+#define mvf_fsl_usb2_udc_data_entry_single(arch, _id) \
+ { \
+ .iobase = arch ## _USBC ## _id ## _BASE_ADDR, \
+ .irq = arch ## _INT_USB ## _id, \
+ }
+
#ifdef CONFIG_SOC_IMX25
const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
imx_fsl_usb2_udc_data_entry_single(MX25);
@@ -44,9 +50,15 @@ const struct imx_fsl_usb2_udc_data imx6q_fsl_usb2_udc_data __initconst =
#endif /* ifdef CONFIG_SOC_IMX6Q */
#ifdef CONFIG_ARCH_MVF
+#ifdef CONFIG_MACH_PCM052
+const struct imx_fsl_usb2_udc_data mvf_fsl_usb2_udc_data[] __initconst = {
+ mvf_fsl_usb2_udc_data_entry_single(MVF, 0),
+ mvf_fsl_usb2_udc_data_entry_single(MVF, 1),
+#else
const struct imx_fsl_usb2_udc_data mvf_fsl_usb2_udc_data __initconst = {
.iobase = MVF_USBC0_BASE_ADDR,
.irq = MVF_INT_USBOTG0,
+#endif
};
#endif
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
index 523c5d4599e1..80c44f48393d 100644
--- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* Copyright (C) 2010 Pengutronix
* Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
@@ -17,6 +17,13 @@
.irq_core = soc ## _INT_USB_ ## hs, \
}
+#define mvf_fsl_usb2_wakeup_data_entry_single(arch, _id) \
+ { \
+ .id = _id, \
+ .irq_phy = arch ## _INT_USB ## _id, \
+ .irq_core = arch ## _INT_USB ## _id, \
+ }
+
#ifdef CONFIG_SOC_IMX6Q
const struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data __initconst =
imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 0, OTG);
@@ -26,6 +33,26 @@ const struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] __initconst = {
imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 3, HS3),
};
#endif /* ifdef CONFIG_SOC_IMX6Q */
+#ifdef CONFIG_SOC_MVFA5
+const struct imx_fsl_usb2_wakeup_data mvf_fsl_otg_wakeup_data[] __initconst = {
+#ifdef CONFIG_MACH_PCM052
+ mvf_fsl_usb2_wakeup_data_entry_single(MVF, 0),
+ mvf_fsl_usb2_wakeup_data_entry_single(MVF, 1),
+#else
+ {
+ .id = 0,
+ .irq_phy = MVF_INT_USBOTG0,
+ .irq_core = MVF_INT_USBOTG0,
+ },
+ {
+ .id = 1,
+ .irq_phy = MVF_INT_USB2,
+ .irq_core = MVF_INT_USB2,
+ }
+#endif
+};
+
+#endif
struct platform_device *__init imx_add_fsl_usb2_wakeup(
const struct imx_fsl_usb2_wakeup_data *data,
diff --git a/arch/arm/plat-mxc/devices/platform-imx-asrc.c b/arch/arm/plat-mxc/devices/platform-imx-asrc.c
index c112a9ba8671..a35617d71a0e 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-asrc.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-asrc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
@@ -38,6 +38,22 @@ const struct imx_imx_asrc_data imx6q_imx_asrc_data[] __initconst = {
};
#endif /* ifdef CONFIG_SOC_IMX6Q */
+#ifdef CONFIG_SOC_MVFA5
+const struct imx_imx_asrc_data mvf_imx_asrc_data[] __initconst = {
+ [0] = {
+ .id = 0,
+ .iobase = MVF_ASRC_BASE_ADDR,
+ .iosize = SZ_4K,
+ .irq = MVF_INT_ASRC,
+ .dmatx1 = DMA_MUX12_ASRC0_TX + 64,
+ .dmarx1 = DMA_MUX12_ASRC0_RX + 64,
+ .dmatx2 = DMA_MUX12_ASRC1_TX + 64,
+ .dmarx2 = DMA_MUX12_ASRC1_RX + 64,
+ .dmatx3 = DMA_MUX12_ASRC2_TX + 64,
+ .dmarx3 = DMA_MUX12_ASRC2_RX + 64,
+ },
+};
+#endif
struct platform_device *__init imx_add_imx_asrc(
const struct imx_imx_asrc_data *data,
const struct imx_asrc_platform_data *pdata)
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pm.c b/arch/arm/plat-mxc/devices/platform-imx-pm.c
index f901e18368c2..2b55d0344830 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-pm.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -30,6 +30,11 @@ const struct imx_pm_imx_data imx6q_pm_imx_data[] __initconst =
imx_pm_imx_data_entry_single(MX6Q);
#endif
+#ifdef CONFIG_SOC_MVFA5
+const struct imx_pm_imx_data mvf_pm_imx_data[] __initconst =
+ imx_pm_imx_data_entry_single(MVF);
+#endif
+
struct platform_device *__init imx_add_pm_imx(
const struct imx_pm_imx_data *data,
const struct pm_platform_data *pdata)
diff --git a/arch/arm/plat-mxc/devices/platform-mvf-adc.c b/arch/arm/plat-mxc/devices/platform-mvf-adc.c
new file mode 100644
index 000000000000..38add8b5fd4f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mvf-adc.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+
+#define mvf_adc_data_entry_single(soc, _id, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ADC ## _id ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ADC ## _id, \
+ }
+#define mvf_adc_data_entry(soc, _id, _size) \
+ [_id] = mvf_adc_data_entry_single(soc, _id, _size)
+
+#ifdef CONFIG_SOC_MVFA5
+const struct mvf_adc_data mvfa5_adc_data[] __initconst = {
+ mvf_adc_data_entry(MVF, 0, SZ_4K),
+};
+#endif
+
+struct platform_device *__init mvf_add_adcdev(
+ const struct mvf_adc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mvf-adc", data->id, res,
+ ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mvf-caam.c b/arch/arm/plat-mxc/devices/platform-mvf-caam.c
new file mode 100644
index 000000000000..0f716911698f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mvf-caam.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+/*
+ * security violation interrupt is used as CAAM base _INT_SNVS_SEC
+ * SNVS consolidated = _INT_SNVS
+ * JR0 = MXC_INT_CAAM_INT0_NUM
+ * JR1 = MXC_INT_CAAM_INT1_NUM
+ */
+
+const struct mvf_caam_data mvf_caam_data __initconst = {
+ .iobase_caam = MVF_CAAM_BASE_ADDR,
+ .iobase_caam_sm = MVF_CAAM_SECMEM_BASE_ADDR,
+ .iobase_snvs = MVF_SNVS_BASE_ADDR,
+ .irq_sec_vio = MVF_INT_SNVS_SEC,
+ .irq_snvs = MVF_INT_SNVS,
+ .jr[0].offset_jr = 0x1000,
+ .jr[0].irq_jr = MVF_INT_CAAM,
+ .jr[1].offset_jr = 0x2000,
+ .jr[1].irq_jr = MVF_INT_CAAM,
+};
+
+struct platform_device *__init mvf_add_caam(
+ const struct mvf_caam_data *data)
+{
+ u32 res_count = 0;
+ struct resource res[] = {
+ {
+ /* Define base range for entire CAAM register map */
+ .name = "iobase_caam",
+ .start = data->iobase_caam,
+ .end = data->iobase_caam + ((SZ_32K + SZ_4K) - 1),
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define range for secure memory */
+ .name = "iobase_caam_sm",
+ .start = data->iobase_caam_sm,
+ .end = data->iobase_caam_sm + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define range for SNVS */
+ .name = "iobase_snvs",
+ .start = data->iobase_snvs,
+ .end = data->iobase_snvs + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define interrupt for security violations */
+ .name = "irq_sec_vio",
+ .start = data->irq_sec_vio,
+ .end = data->irq_sec_vio,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* Define general SNVS interrupt */
+ .name = "irq_snvs",
+ .start = data->irq_snvs,
+ .end = data->irq_snvs,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "offset_jr0",
+ .start = data->jr[0].offset_jr,
+ .end = data->jr[0].offset_jr,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_jr0",
+ .start = data->jr[0].irq_jr,
+ .end = data->jr[0].irq_jr,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "offset_jr1",
+ .start = data->jr[1].offset_jr,
+ .end = data->jr[1].offset_jr,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_jr1",
+ .start = data->jr[1].irq_jr,
+ .end = data->jr[1].irq_jr,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ res_count = ARRAY_SIZE(res);
+ BUG_ON(!res_count);
+
+ return imx_add_platform_device("caam", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
index f700d656c3b7..928f3b792e0f 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
@@ -16,6 +16,13 @@
.irq = soc ## _INT_USB_ ## hs, \
}
+#define mvf_mxc_ehci_data_entry_single(arch, _id) \
+ { \
+ .id = _id, \
+ .iobase = arch ## _USBC ## _id ## _BASE_ADDR, \
+ .irq = arch ## _INT_USB ## _id, \
+ }
+
#ifdef CONFIG_SOC_IMX25
const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst =
imx_mxc_ehci_data_entry_single(MX25, 0, OTG);
@@ -59,12 +66,18 @@ const struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] __initconst = {
#endif /* ifdef CONFIG_SOC_IMX6Q */
#ifdef CONFIG_ARCH_MVF
+#ifdef CONFIG_MACH_PCM052
+const struct imx_mxc_ehci_data mvf_mxc_ehci_otg_data[] __initconst = {
+ mvf_mxc_ehci_data_entry_single(MVF, 0),
+ mvf_mxc_ehci_data_entry_single(MVF, 1),
+#else
const struct imx_mxc_ehci_data mvf_mxc_ehci_otg_data __initconst = {
.id = 0,
.iobase = MVF_USBC1_BASE_ADDR,
.irq = MVF_INT_USB2,
-};
#endif
+};
+#endif /* ifdef CONFIG_ARCH_MVF */
struct platform_device *__init imx_add_mxc_ehci(
const struct imx_mxc_ehci_data *data,
diff --git a/arch/arm/plat-mxc/include/mach/arc_otg.h b/arch/arm/plat-mxc/include/mach/arc_otg.h
index 51945e0fa957..af06f51759e5 100755
--- a/arch/arm/plat-mxc/include/mach/arc_otg.h
+++ b/arch/arm/plat-mxc/include/mach/arc_otg.h
@@ -31,7 +31,7 @@ extern void __iomem *imx_otg_base;
#define USB_OTGREGS_BASE MVF_IO_ADDRESS(0x40034000)
#define USB_OTG2REGS_BASE MVF_IO_ADDRESS(0x400B4000)
-#define USB_H1REGS_BASE MVF_IO_ADDRESS(0x400B4000)
+#define USB_H1REGS_BASE MVF_IO_ADDRESS(0x40034000)
/* dummy h2regs for MVF */
#define USB_H2REGS_BASE MVF_IO_ADDRESS(0x400B4000)
#define USBC0_OTHERREGS_BASE MVF_IO_ADDRESS(0x40034800)
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index a8a8034c1010..0e2a2a1d13e9 100755
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -89,6 +89,15 @@ struct imx_imx2_wdt_data {
struct platform_device *__init imx_add_imx2_wdt(
const struct imx_imx2_wdt_data *data);
+struct mvf_adc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mvf_add_adcdev(
+ const struct mvf_adc_data *data);
+
struct imx_imxdi_rtc_data {
resource_size_t iobase;
resource_size_t irq;
@@ -672,3 +681,20 @@ struct imx_rngb_data {
struct platform_device *__init imx_add_rngb(
const struct imx_rngb_data *data);
+
+struct mvf_caam_jr_data {
+ resource_size_t offset_jr;
+ resource_size_t irq_jr;
+};
+
+struct mvf_caam_data {
+ resource_size_t iobase_caam; /* entirety of CAAM register map */
+ resource_size_t iobase_caam_sm; /* base of secure memory */
+ resource_size_t iobase_snvs; /* base of SNVS */
+ resource_size_t irq_sec_vio; /* SNVS security violation */
+ resource_size_t irq_snvs; /* SNVS consolidated (incl. RTC) */
+ struct mvf_caam_jr_data jr[4]; /* offset+IRQ for each possible ring */
+};
+
+struct platform_device *__init mvf_add_caam(
+ const struct mvf_caam_data *data);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mvf.h b/arch/arm/plat-mxc/include/mach/iomux-mvf.h
index a838e0bbead9..eb093e2c0f7f 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mvf.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mvf.h
@@ -40,9 +40,8 @@ typedef enum iomux_config {
#define NON_MUX_I 0x3FF
#define NON_PAD_I 0x7FF
-#define MVF600_SDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
- PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_HIGH | \
- PAD_CTL_DSE_20ohm | PAD_CTL_OBE_IBE_ENABLE)
+#define MVF600_SDHC_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_50ohm | PAD_CTL_OBE_IBE_ENABLE)
#define MVF600_ENET_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
PAD_CTL_DSE_50ohm)
@@ -196,16 +195,19 @@ typedef enum iomux_config {
MVF600_ENET_PAD_CTRL | PAD_CTL_OBE_ENABLE)
/*USB0/1 VBUS, using the GPIO*/
-#define MVF600_PAD134_PTA7__USB0_VBUS_EN \
+#define MVF600_PAD134_PTA7__USB_VBUS_EN \
IOMUX_PAD(0x0218, 0x0218, 0, 0x0000, 0, \
- MVF600_GPIO_GENERAL_CTRL | PAD_CTL_OBE_ENABLE)
+ PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_25ohm | \
+ PAD_CTL_SPEED_LOW | PAD_CTL_OBE_ENABLE)
#define MVF600_PAD6_PTA16__USB0_VBUS_EN \
IOMUX_PAD(0x0018, 0x0018, 0, 0x0000, 0, \
- MVF600_GPIO_GENERAL_CTRL | PAD_CTL_OBE_ENABLE)
-
+ PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_25ohm | \
+ PAD_CTL_SPEED_LOW | PAD_CTL_OBE_ENABLE)
#define MVF600_PAD7_PTA17__USB_OC_N \
IOMUX_PAD(0x001C, 0x001C, 2, 0x0000, 0, \
- PAD_CTL_DSE_20ohm | PAD_CTL_IBE_ENABLE)
+ PAD_CTL_HYS | PAD_CTL_IBE_ENABLE)
/*ESAI0(share with FEC1)*/
#define MVF600_PAD54_PTC9__ESAI_SCKT \
diff --git a/arch/arm/plat-mxc/include/mach/mvf.h b/arch/arm/plat-mxc/include/mach/mvf.h
index 9ef4de35d4c0..4a47636fa741 100644
--- a/arch/arm/plat-mxc/include/mach/mvf.h
+++ b/arch/arm/plat-mxc/include/mach/mvf.h
@@ -53,8 +53,7 @@
* IRAM
*/
#define MVF_IRAM_BASE_ADDR 0x3F000000 /* internal ram */
-#define MVF_IRAM_PARTITIONS 2
-#define MVF_IRAM_SIZE (MVF_IRAM_PARTITIONS * SZ_256K) /* 512KB */
+#define MVF_IRAM_SIZE (SZ_256K) /* 256KB */
#ifdef CONFIG_MXC_VPU_IRAM
@@ -146,7 +145,7 @@
#define MVF_PIT_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00037000)
#define MVF_FTM0_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00038000)
#define MVF_FTM1_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00039000)
-#define MVF_ADC_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0003B000)
+#define MVF_ADC0_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0003B000)
#define MVF_TCON0_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0003D000)
#define MVF_WDOG1_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0003E000)
#define MVF_LPTMR_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00040000)
@@ -169,24 +168,29 @@
#define MVF_EWM_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00065000)
#define MVF_I2C0_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00066000)
#define MVF_I2C1_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x00067000)
-#define MVF_WKUP_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006A000)
+#define MVF_WKPU_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006A000)
#define MVF_CCM_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006B000)
-#define MVF_GPC_BASE_ADDR (MVF_AIPS1_BASE_ADDR + 0x0006C000)
-#define MVF_VREG_BASE_ADDR (MVF_AIPS1_BASE_ADDR + 0x0006D000)
-#define MVF_SRC_BASE_ADDR (MVF_AIPS1_BASE_ADDR + 0x0006E000)
+#define MVF_GPC_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006C000)
+#define MVF_VREG_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006D000)
+#define MVF_SRC_BASE_ADDR (MVF_AIPS0_BASE_ADDR + 0x0006E000)
#define MVF_CMU_BASE_ADDR (MVF_AIPS1_BASE_ADDR + 0x0006F000)
+#define MVF_CAAM_SECMEM_BASE_ADDR \
+ (MVF_AIPS0_BASE_ADDR + 0x0007C000)
+#define MVF_CAAM_SECMEM_END_ADDR \
+ (MVF_AIPS0_BASE_ADDR + 0x0007FFFF)
+
#define L2_BASE_ADDR MVF_L2C_BASE_ADDR
-#define MVF_USBC0_CTRL_BASE_ADDR 0x40034800
-#define MVF_USBC1_CTRL_BASE_ADDR 0x400B4800
-#define MVF_USBC0_PHY_BASE_ADDR 0x40034818
-#define MVF_USBC1_PHY_BASE_ADDR 0x400B4818
+#define MVF_USBC0_CTRL_BASE_ADDR 0x40035800
+#define MVF_USBC1_CTRL_BASE_ADDR 0x400B5800
+#define MVF_USBC0_PHY_BASE_ADDR 0x40035818
+#define MVF_USBC1_PHY_BASE_ADDR 0x400B5818
#define MVF_USBC0_BASE_ADDR 0x40034000
#define MVF_USBC1_BASE_ADDR 0x400B4000
#define MVF_USBPHY0_BASE_ADDR 0x40050800
-#define MVF_USBPHY1_BASE_ADDR 0x40050B00
+#define MVF_USBPHY1_BASE_ADDR 0x40050C00
#define MVF_MSCM_INT_ROUTER_BASE (MVF_MSCM_BASE_ADDR + 0x800)
@@ -283,6 +287,12 @@
#define MVF_PGC_GPU_PGCR (MVF_PGC_GPU_BASE + 0x0)
#define MVF_PGC_GPU_PGSR (MVF_PGC_GPU_BASE + 0xC)
+/* Voltage Regulators */
+#define MVF_VREG_BASE (MVF_IO_ADDRESS(MVF_VREG_BASE_ADDR))
+
+/* WKPU */
+#define MVF_WKPU_BASE (MVF_IO_ADDRESS(MVF_WKPU_BASE_ADDR))
+
/*
* defines for SPBA modules
*/
@@ -543,8 +553,13 @@
#define MVF_INT_I2C1 104
#define MVF_INT_I2C2 105
#define MVF_INT_I2C3 106
-#define MVF_INT_USBOTG0 107
-#define MVF_INT_USB2 108
+
+#ifdef CONFIG_MACH_PCM052
+#define MVF_INT_USB0 107
+#define MVF_INT_USB1 108
+#else
+#endif
+
#define MVF_INT_ENET_MAC0 110
#define MVF_INT_ENET_MAC1 111
#define MVF_INT_1588_TIMER0 112
@@ -558,15 +573,16 @@
#define MVF_INT_ESAI_BIFIFO 120
#define MVF_INT_SPDIF 121
#define MVF_INT_ASRC 122
-#define MVF_INT_CMU 123
+#define MVF_INT_CMU 123
#define MVF_INT_WKPU0 124
#define MVF_INT_WKPU1 125
-#define MVF_INT_CCM 126
+#define MVF_INT_CCM 126
-#define MVF_INT_SRC 128
-#define MVF_INT_PDB 129
-#define MVF_INT_EWM 130
+#define MVF_INT_SRC 128
+#define MVF_INT_PDB 129
+#define MVF_INT_EWM 130
#define MVF_INT_SNVS 132
+#define MVF_INT_SNVS_SEC 133
#define MVF_INT_CAAM 134
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index afcf1255150b..b291d9015025 100755
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -257,6 +257,15 @@ struct cpu_op {
u32 cpu_podf;
};
+#ifdef CONFIG_SOC_MVFA5
+enum mvf_cpu_pwr_mode {
+ RUN_MODE,
+ LOW_POWER_RUN,
+ WAIT_MODE,
+ STOP_MODE,
+ LOW_POWER_STOP,
+};
+#else
enum mxc_cpu_pwr_mode {
WAIT_CLOCKED, /* wfi only */
WAIT_UNCLOCKED, /* WAIT */
@@ -265,10 +274,15 @@ enum mxc_cpu_pwr_mode {
STOP_POWER_OFF, /* STOP + SRPG */
ARM_POWER_OFF, /* STOP + SRPG + ARM power off */
};
+#endif
int tzic_enable_wake(int is_idle);
+#ifdef CONFIG_SOC_MVFA5
+extern void mvf_cpu_lp_set(enum mvf_cpu_pwr_mode mode);
+#else
extern void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+#endif
extern int tzic_enable_wake(int is_idle);
#endif
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
index 0aa3d590d1d2..96cede81d319 100755
--- a/arch/arm/plat-mxc/usb_common.c
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -1049,6 +1049,9 @@ EXPORT_SYMBOL(usb_debounce_id_vbus);
int usb_event_is_otg_wakeup(struct fsl_usb2_platform_data *pdata)
{
+#ifdef CONFIG_ARCH_MVF
+ return false;
+#endif
return (USBCTRL & UCTRL_OWIR) ? true : false;
}
EXPORT_SYMBOL(usb_event_is_otg_wakeup);
diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c
index 4704eae91a51..7187eff67426 100755
--- a/arch/arm/plat-mxc/usb_wakeup.c
+++ b/arch/arm/plat-mxc/usb_wakeup.c
@@ -36,7 +36,8 @@ struct wakeup_ctrl {
struct task_struct *thread;
struct completion event;
};
-static struct wakeup_ctrl *g_ctrl;
+static struct wakeup_ctrl *g_ctrl[2];
+static unsigned int g_ctrls;
extern int usb_event_is_otg_wakeup(struct fsl_usb2_platform_data *pdata);
extern void usb_debounce_id_vbus(void);
@@ -166,7 +167,7 @@ static int wakeup_dev_probe(struct platform_device *pdev)
int status;
unsigned long interrupt_flag;
- printk(KERN_INFO "IMX usb wakeup probe\n");
+ printk(KERN_INFO "IMX usb wakeup probe. id=%d\n", pdev->id);
if (!pdev || !pdev->dev.platform_data)
return -ENODEV;
@@ -192,11 +193,12 @@ static int wakeup_dev_probe(struct platform_device *pdev)
if (status)
goto error1;
- ctrl->thread = kthread_run(wakeup_event_thread, (void *)ctrl, "usb_wakeup thread");
+ ctrl->thread = kthread_run(wakeup_event_thread, (void *)ctrl,
+ "usb_wakeup:%d", pdev->id);
status = IS_ERR(ctrl->thread) ? -1 : 0;
if (status)
goto error2;
- g_ctrl = ctrl;
+ g_ctrl[g_ctrls++] = ctrl;
printk(KERN_DEBUG "the wakeup pdata is 0x%p\n", pdata);
return 0;
@@ -209,12 +211,17 @@ error1:
static int wakeup_dev_exit(struct platform_device *pdev)
{
- if (g_ctrl->thread) {
- complete(&g_ctrl->event);
- kthread_stop(g_ctrl->thread);
+ int i;
+ for (i = 0; i < g_ctrls; i++) {
+ if (g_ctrl[i]->thread) {
+ complete(&g_ctrl[i]->event);
+ kthread_stop(g_ctrl[i]->thread);
+ }
+ free_irq(g_ctrl[i]->wakeup_irq, (void *)g_ctrl[i]);
+ kfree(g_ctrl[i]);
+ g_ctrl[i] = NULL;
+ g_ctrls = 0;
}
- free_irq(g_ctrl->wakeup_irq, (void *)g_ctrl);
- kfree(g_ctrl);
return 0;
}
static struct platform_driver wakeup_d = {