summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6
diff options
context:
space:
mode:
authorJack Lee <jacklee@freescale.com>2012-09-05 10:21:49 +0800
committerJack Lee <jacklee@freescale.com>2012-09-05 10:21:49 +0800
commita0619e1d6c1c51a367b8d0bf74bb9058df919545 (patch)
treed40e30c91892ea35c82d22a8364b9b9548e42b7a /arch/arm/mach-mx6
parent65745dd4b7f80711d03dce5529fc501162428c53 (diff)
parent85a6685fb327f1eebaeea5dfc04a6750573472ef (diff)
Merge commit 'rel_imx_3.0.35_12.09.02_RC1' into imx_3.0.35_android_r13.5-beta
Conflicts: arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/mach-mx6/board-mx6sl_arm2.c arch/arm/mach-mx6/bus_freq.c arch/arm/mach-mx6/cpu_op-mx6.c arch/arm/plat-mxc/cpufreq.c Signed-off-by: Jack Lee <jacklee@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx6')
-rw-r--r--arch/arm/mach-mx6/Kconfig37
-rw-r--r--arch/arm/mach-mx6/Makefile5
-rw-r--r--arch/arm/mach-mx6/board-mx6dl_arm2.h4
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c6
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c14
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c14
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_arm2.c498
-rw-r--r--[-rwxr-xr-x]arch/arm/mach-mx6/board-mx6sl_common.h (renamed from arch/arm/mach-mx6/board-mx6sl_arm2.h)73
-rw-r--r--arch/arm/mach-mx6/board-mx6sl_evk.c1320
-rw-r--r--arch/arm/mach-mx6/bus_freq.c415
-rw-r--r--arch/arm/mach-mx6/clock.c73
-rwxr-xr-xarch/arm/mach-mx6/clock_mx6sl.c117
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c230
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h7
-rw-r--r--arch/arm/mach-mx6/irq.c16
-rw-r--r--arch/arm/mach-mx6/mx6_anatop_regulator.c4
-rw-r--r--arch/arm/mach-mx6/mx6_suspend.S14
-rw-r--r--arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c6
-rw-r--r--arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c29
-rw-r--r--arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c29
-rw-r--r--arch/arm/mach-mx6/mx6sl_ddr.S432
-rw-r--r--arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c464
-rw-r--r--arch/arm/mach-mx6/mx6sl_wfi.S412
-rw-r--r--arch/arm/mach-mx6/pm.c6
-rw-r--r--arch/arm/mach-mx6/system.c74
-rw-r--r--arch/arm/mach-mx6/usb.h3
-rw-r--r--arch/arm/mach-mx6/usb_dr.c43
-rw-r--r--arch/arm/mach-mx6/usb_h1.c38
-rw-r--r--arch/arm/mach-mx6/usb_h2.c11
29 files changed, 3799 insertions, 595 deletions
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 08875a60a31c..45ae9eac67d2 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -107,6 +107,43 @@ config MACH_MX6SL_ARM2
Include support for i.MX 6Sololite Armadillo2 platform. This includes specific
configurations for the board and its peripherals.
+config MACH_MX6SL_EVK
+ bool "Support i.MX 6SoloLite EVK platform"
+ select ARCH_MX6Q
+ select SOC_IMX6SL
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+ select IMX_HAVE_PLATFORM_IMX_SPDC
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_DCP
+ select IMX_HAVE_PLATFORM_RANDOM_RNGC
+ select ARCH_HAS_RNGC
+ help
+ Include support for i.MX 6Sololite EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
config MACH_MX6Q_SABRELITE
bool "Support i.MX 6Quad SABRE Lite platform"
select ARCH_MX6Q
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index 24dae23dd089..49b5f86a6920 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -5,15 +5,16 @@
# Object file lists.
obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o usb_h2.o usb_h3.o\
pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \
-mx6_mmdc.o mx6_ddr_freq.o
+mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o mx6sl_wfi.o
obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o
obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o
obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o
+obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o
obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o
obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o
obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o
obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
obj-$(CONFIG_IMX_PCIE) += pcie.o
-obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o \ No newline at end of file
+obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o
diff --git a/arch/arm/mach-mx6/board-mx6dl_arm2.h b/arch/arm/mach-mx6/board-mx6dl_arm2.h
index 6ed3e65e68ee..429febb9813d 100644
--- a/arch/arm/mach-mx6/board-mx6dl_arm2.h
+++ b/arch/arm/mach-mx6/board-mx6dl_arm2.h
@@ -188,7 +188,9 @@ static iomux_v3_cfg_t mx6dl_arm2_pads[] = {
MX6DL_PAD_GPIO_6__MLB_MLBSIG,
MX6DL_PAD_GPIO_2__MLB_MLBDAT,
- /* EPDC pins */
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_epdc_pads[] = {
MX6DL_PAD_EIM_A17__GPIO_2_21,
MX6DL_PAD_EIM_D17__GPIO_3_17,
MX6DL_PAD_EIM_A18__GPIO_2_20,
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index 62db4d47ba41..c604319ef986 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -2005,12 +2005,14 @@ static void __init mx6_arm2_init(void)
iomux_v3_cfg_t *spdif_pads = NULL;
iomux_v3_cfg_t *flexcan_pads = NULL;
iomux_v3_cfg_t *i2c3_pads = NULL;
+ iomux_v3_cfg_t *epdc_pads = NULL;
int common_pads_cnt;
int esai_rec_pads_cnt;
int spdif_pads_cnt;
int flexcan_pads_cnt;
int i2c3_pads_cnt;
+ int epdc_pads_cnt;
/*
@@ -2036,12 +2038,14 @@ static void __init mx6_arm2_init(void)
spdif_pads = mx6dl_arm2_spdif_pads;
flexcan_pads = mx6dl_arm2_can_pads;
i2c3_pads = mx6dl_arm2_i2c3_pads;
+ epdc_pads = mx6dl_arm2_epdc_pads;
common_pads_cnt = ARRAY_SIZE(mx6dl_arm2_pads);
esai_rec_pads_cnt = ARRAY_SIZE(mx6dl_arm2_esai_record_pads);
spdif_pads_cnt = ARRAY_SIZE(mx6dl_arm2_spdif_pads);
flexcan_pads_cnt = ARRAY_SIZE(mx6dl_arm2_can_pads);
i2c3_pads_cnt = ARRAY_SIZE(mx6dl_arm2_i2c3_pads);
+ epdc_pads_cnt = ARRAY_SIZE(mx6dl_arm2_epdc_pads);
}
BUG_ON(!common_pads);
@@ -2222,6 +2226,8 @@ static void __init mx6_arm2_init(void)
imx6q_add_mlb150(&mx6_arm2_mlb150_data);
if (cpu_is_mx6dl() && epdc_enabled) {
+ BUG_ON(!epdc_pads);
+ mxc_iomux_v3_setup_multiple_pads(epdc_pads, epdc_pads_cnt);
imx6dl_add_imx_pxp();
imx6dl_add_imx_pxp_client();
mxc_register_device(&max17135_sensor_device, NULL);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index d972cda66750..530466dd7b2f 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -576,6 +576,15 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
},
};
+static void mx6q_csi0_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 1);
+ else
+ gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 0);
+
+ msleep(2);
+}
static void mx6q_csi0_io_init(void)
{
@@ -616,6 +625,7 @@ static struct fsl_mxc_camera_platform_data camera_data = {
.mclk_source = 0,
.csi = 0,
.io_init = mx6q_csi0_io_init,
+ .pwdn = mx6q_csi0_cam_powerdown,
};
static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
@@ -1260,6 +1270,10 @@ static void __init mx6_sabrelite_board_init(void)
clk_set_rate(clko2, rate);
clk_enable(clko2);
imx6q_add_busfreq();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
}
extern void __iomem *twd_base;
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index 3a02094869e7..9bb1ee3f93ed 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -1592,13 +1592,14 @@ static struct platform_pwm_backlight_data mx6_sabresd_pwm_backlight_data = {
};
static struct mxc_dvfs_platform_data sabresd_dvfscore_data = {
- #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
.reg_id = "VDDCORE",
- #else
+ .soc_id = "VDDSOC",
+#else
.reg_id = "cpu_vddgp",
.soc_id = "cpu_vddsoc",
.pu_id = "cpu_vddvpu",
- #endif
+#endif
.clk1_id = "cpu_clk",
.clk2_id = "gpc_dvfs_clk",
.gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
@@ -1824,12 +1825,9 @@ static void __init mx6_sabresd_board_init(void)
imx6q_add_dma();
imx6q_add_dvfs_core(&sabresd_dvfscore_data);
- #ifndef CONFIG_MX6_INTER_LDO_BYPASS
+#ifndef CONFIG_MX6_INTER_LDO_BYPASS
mx6_cpu_regulator_init();
- #endif
-
- imx6q_add_ion(0, &imx_ion_data,
- sizeof(imx_ion_data) + sizeof(struct ion_platform_heap));
+#endif
imx6q_add_device_buttons();
/* enable sensor 3v3 and 1v8 */
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c
index 249912b82d04..419b2447e215 100755
--- a/arch/arm/mach-mx6/board-mx6sl_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c
@@ -33,7 +33,6 @@
#include <linux/spi/flash.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
-#include <linux/ata.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
@@ -71,67 +70,11 @@
#include "devices-imx6q.h"
#include "crm_regs.h"
#include "cpu_op-mx6.h"
-#include "board-mx6sl_arm2.h"
-
-#define MX6_ARM2_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */
-#define MX6_ARM2_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */
-#define MX6_ARM2_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */
-#define MX6_ARM2_SD1_WP IMX_GPIO_NR(4, 6) /* KEY_COL7 */
-#define MX6_ARM2_SD1_CD IMX_GPIO_NR(4, 7) /* KEY_ROW7 */
-#define MX6_ARM2_ECSPI1_CS0 IMX_GPIO_NR(4, 11) /* ECSPI1_SS0 */
-#define MX6_ARM2_HEADPHONE_DET IMX_GPIO_NR(4, 19) /* FEC_RX_ER */
-#define MX6_ARM2_SD2_WP IMX_GPIO_NR(4, 29) /* SD2_DAT6 */
-#define MX6_ARM2_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */
-#define MX6_ARM2_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */
-#define MX6_ARM2_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */
-
-/* EPDC GPIO pins */
-#define MX6SL_ARM2_EPDC_SDDO_0 IMX_GPIO_NR(1, 7)
-#define MX6SL_ARM2_EPDC_SDDO_1 IMX_GPIO_NR(1, 8)
-#define MX6SL_ARM2_EPDC_SDDO_2 IMX_GPIO_NR(1, 9)
-#define MX6SL_ARM2_EPDC_SDDO_3 IMX_GPIO_NR(1, 10)
-#define MX6SL_ARM2_EPDC_SDDO_4 IMX_GPIO_NR(1, 11)
-#define MX6SL_ARM2_EPDC_SDDO_5 IMX_GPIO_NR(1, 12)
-#define MX6SL_ARM2_EPDC_SDDO_6 IMX_GPIO_NR(1, 13)
-#define MX6SL_ARM2_EPDC_SDDO_7 IMX_GPIO_NR(1, 14)
-#define MX6SL_ARM2_EPDC_SDDO_8 IMX_GPIO_NR(1, 15)
-#define MX6SL_ARM2_EPDC_SDDO_9 IMX_GPIO_NR(1, 16)
-#define MX6SL_ARM2_EPDC_SDDO_10 IMX_GPIO_NR(1, 17)
-#define MX6SL_ARM2_EPDC_SDDO_11 IMX_GPIO_NR(1, 18)
-#define MX6SL_ARM2_EPDC_SDDO_12 IMX_GPIO_NR(1, 19)
-#define MX6SL_ARM2_EPDC_SDDO_13 IMX_GPIO_NR(1, 20)
-#define MX6SL_ARM2_EPDC_SDDO_14 IMX_GPIO_NR(1, 21)
-#define MX6SL_ARM2_EPDC_SDDO_15 IMX_GPIO_NR(1, 22)
-#define MX6SL_ARM2_EPDC_GDCLK IMX_GPIO_NR(1, 31)
-#define MX6SL_ARM2_EPDC_GDSP IMX_GPIO_NR(2, 2)
-#define MX6SL_ARM2_EPDC_GDOE IMX_GPIO_NR(2, 0)
-#define MX6SL_ARM2_EPDC_GDRL IMX_GPIO_NR(2, 1)
-#define MX6SL_ARM2_EPDC_SDCLK IMX_GPIO_NR(1, 23)
-#define MX6SL_ARM2_EPDC_SDOE IMX_GPIO_NR(1, 25)
-#define MX6SL_ARM2_EPDC_SDLE IMX_GPIO_NR(1, 24)
-#define MX6SL_ARM2_EPDC_SDSHR IMX_GPIO_NR(1, 26)
-#define MX6SL_ARM2_EPDC_PWRCOM IMX_GPIO_NR(2, 11)
-#define MX6SL_ARM2_EPDC_PWRSTAT IMX_GPIO_NR(2, 13)
-#define MX6SL_ARM2_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 7)
-#define MX6SL_ARM2_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 8)
-#define MX6SL_ARM2_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 9)
-#define MX6SL_ARM2_EPDC_PWRCTRL3 IMX_GPIO_NR(2, 10)
-#define MX6SL_ARM2_EPDC_BDR0 IMX_GPIO_NR(2, 5)
-#define MX6SL_ARM2_EPDC_BDR1 IMX_GPIO_NR(2, 6)
-#define MX6SL_ARM2_EPDC_SDCE0 IMX_GPIO_NR(1, 27)
-#define MX6SL_ARM2_EPDC_SDCE1 IMX_GPIO_NR(1, 28)
-#define MX6SL_ARM2_EPDC_SDCE2 IMX_GPIO_NR(1, 29)
-#define MX6SL_ARM2_EPDC_SDCE3 IMX_GPIO_NR(1, 30)
-#define MX6SL_ARM2_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */
-#define MX6SL_ARM2_EPDC_PMIC_INT IMX_GPIO_NR(2, 12) /* EPDC_PWRINT */
-#define MX6SL_ARM2_EPDC_VCOM IMX_GPIO_NR(2, 3)
-#define MX6SL_ARM2_ELAN_CE IMX_GPIO_NR(2, 9)
-#define MX6SL_ARM2_ELAN_INT IMX_GPIO_NR(2, 10)
-#define MX6SL_ARM2_ELAN_RST IMX_GPIO_NR(4, 4)
+#include "board-mx6sl_common.h"
static int spdc_sel;
static int max17135_regulator_init(struct max17135 *max17135);
-struct clk *extern_audio_root;
+static struct clk *extern_audio_root;
extern char *gp_reg_id;
extern char *soc_reg_id;
@@ -215,8 +158,8 @@ static int plt_sd_pad_change(unsigned int index, int clock)
}
static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = {
- .cd_gpio = MX6_ARM2_SD1_CD,
- .wp_gpio = MX6_ARM2_SD1_WP,
+ .cd_gpio = MX6_BRD_SD1_CD,
+ .wp_gpio = MX6_BRD_SD1_WP,
.support_8bit = 1,
.support_18v = 1,
.keep_power_at_suspend = 1,
@@ -225,8 +168,8 @@ static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = {
};
static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = {
- .cd_gpio = MX6_ARM2_SD2_CD,
- .wp_gpio = MX6_ARM2_SD2_WP,
+ .cd_gpio = MX6_BRD_SD2_CD,
+ .wp_gpio = MX6_BRD_SD2_WP,
.keep_power_at_suspend = 1,
.delay_line = 0,
.support_18v = 1,
@@ -234,7 +177,7 @@ static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = {
};
static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
- .cd_gpio = MX6_ARM2_SD3_CD,
+ .cd_gpio = MX6_BRD_SD3_CD,
.wp_gpio = -1,
.keep_power_at_suspend = 1,
.delay_line = 0,
@@ -377,11 +320,11 @@ static struct max17135_platform_data max17135_pdata __initdata = {
.vpos_pwrdn = 2,
.gvee_pwrdn = 1,
.vneg_pwrdn = 1,
- .gpio_pmic_pwrgood = MX6SL_ARM2_EPDC_PWRSTAT,
- .gpio_pmic_vcom_ctrl = MX6SL_ARM2_EPDC_VCOM,
- .gpio_pmic_wakeup = MX6SL_ARM2_EPDC_PMIC_WAKE,
- .gpio_pmic_v3p3 = MX6SL_ARM2_EPDC_PWRCTRL0,
- .gpio_pmic_intr = MX6SL_ARM2_EPDC_PMIC_INT,
+ .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT,
.regulator_init = max17135_init_data,
.init = max17135_regulator_init,
};
@@ -448,7 +391,7 @@ static int __init max17135_regulator_init(struct max17135 *max17135)
}
static int mx6_arm2_spi_cs[] = {
- MX6_ARM2_ECSPI1_CS0,
+ MX6_BRD_ECSPI1_CS0,
};
static const struct spi_imx_master mx6_arm2_spi_data __initconst = {
@@ -551,7 +494,7 @@ static struct mxc_audio_platform_data wm8962_data = {
.ssi_num = 1,
.src_port = 2,
.ext_port = 3,
- .hp_gpio = MX6_ARM2_HEADPHONE_DET,
+ .hp_gpio = MX6_BRD_HEADPHONE_DET,
.hp_active_low = 1,
.mic_gpio = -1,
.mic_active_low = 1,
@@ -618,7 +561,9 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
.platform_data = &max17135_pdata,
}, {
I2C_BOARD_INFO("elan-touch", 0x10),
- .irq = gpio_to_irq(MX6SL_ARM2_ELAN_INT),
+ .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT),
+ }, {
+ I2C_BOARD_INFO("mma8450", 0x1c),
},
};
@@ -635,13 +580,14 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
};
static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = {
- #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
.reg_id = "VDDCORE",
- #else
+ .soc_id = "VDDSOC",
+#else
.reg_id = "cpu_vddgp",
.soc_id = "cpu_vddsoc",
.pu_id = "cpu_vddvpu",
- #endif
+#endif
.clk1_id = "cpu_clk",
.clk2_id = "gpc_dvfs_clk",
.gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
@@ -679,11 +625,11 @@ static int mx6sl_arm2_fec_phy_init(struct phy_device *phydev)
int val;
/* power on FEC phy and reset phy */
- gpio_request(MX6_ARM2_FEC_PWR_EN, "fec-pwr");
- gpio_direction_output(MX6_ARM2_FEC_PWR_EN, 0);
+ gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr");
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0);
/* wait RC ms for hw reset */
msleep(1);
- gpio_direction_output(MX6_ARM2_FEC_PWR_EN, 1);
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1);
/* check phy power */
val = phy_read(phydev, 0x0);
@@ -704,109 +650,109 @@ static int epdc_get_pins(void)
int ret = 0;
/* Claim GPIOs for EPDC pins - used during power up/down */
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_0, "epdc_d0");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_1, "epdc_d1");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_2, "epdc_d2");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_3, "epdc_d3");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_4, "epdc_d4");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_5, "epdc_d5");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_6, "epdc_d6");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_7, "epdc_d7");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDCLK, "epdc_gdclk");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDSP, "epdc_gdsp");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDOE, "epdc_gdoe");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDRL, "epdc_gdrl");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCLK, "epdc_sdclk");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDOE, "epdc_sdoe");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDLE, "epdc_sdle");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDSHR, "epdc_sdshr");
- ret |= gpio_request(MX6SL_ARM2_EPDC_BDR0, "epdc_bdr0");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE0, "epdc_sdce0");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE1, "epdc_sdce1");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE2, "epdc_sdce2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2");
return ret;
}
static void epdc_put_pins(void)
{
- gpio_free(MX6SL_ARM2_EPDC_SDDO_0);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_1);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_2);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_3);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_4);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_5);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_6);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_7);
- gpio_free(MX6SL_ARM2_EPDC_GDCLK);
- gpio_free(MX6SL_ARM2_EPDC_GDSP);
- gpio_free(MX6SL_ARM2_EPDC_GDOE);
- gpio_free(MX6SL_ARM2_EPDC_GDRL);
- gpio_free(MX6SL_ARM2_EPDC_SDCLK);
- gpio_free(MX6SL_ARM2_EPDC_SDOE);
- gpio_free(MX6SL_ARM2_EPDC_SDLE);
- gpio_free(MX6SL_ARM2_EPDC_SDSHR);
- gpio_free(MX6SL_ARM2_EPDC_BDR0);
- gpio_free(MX6SL_ARM2_EPDC_SDCE0);
- gpio_free(MX6SL_ARM2_EPDC_SDCE1);
- gpio_free(MX6SL_ARM2_EPDC_SDCE2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_GDRL);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_BDR0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCE2);
}
static void epdc_enable_pins(void)
{
/* Configure MUX settings to enable EPDC use */
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_epdc_enable_pads, \
- ARRAY_SIZE(mx6sl_arm2_epdc_enable_pads));
-
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_0);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_1);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_2);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_3);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_4);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_5);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_6);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_7);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDCLK);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDSP);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDOE);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDRL);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCLK);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDOE);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDLE);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDSHR);
- gpio_direction_input(MX6SL_ARM2_EPDC_BDR0);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCE0);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCE1);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCE2);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDRL);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_BDR0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE2);
}
static void epdc_disable_pins(void)
{
/* Configure MUX settings for EPDC pins to
* GPIO and drive to 0. */
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_epdc_disable_pads, \
- ARRAY_SIZE(mx6sl_arm2_epdc_disable_pads));
-
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_0, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_1, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_2, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_3, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_4, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_5, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_6, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_7, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDCLK, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDSP, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDOE, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDRL, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCLK, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDOE, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDLE, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDSHR, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_BDR0, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCE0, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCE1, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCE2, 0);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0);
}
static struct fb_videomode e60_v110_mode = {
@@ -946,108 +892,108 @@ static int spdc_get_pins(void)
int ret = 0;
/* Claim GPIOs for SPDC pins - used during power up/down */
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_0, "SPDC_D0");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_1, "SPDC_D1");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_2, "SPDC_D2");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_3, "SPDC_D3");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_4, "SPDC_D4");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_5, "SPDC_D5");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_6, "SPDC_D6");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_7, "SPDC_D7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDOE, "SIPIX_YOE");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_9, "SIPIX_PWR_RDY");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDSP, "SIPIX_YDIO");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO");
- ret |= gpio_request(MX6SL_ARM2_EPDC_GDCLK, "SIPIX_YCLK");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDSHR, "SIPIX_XDIO");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDLE, "SIPIX_LD");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE1, "SIPIX_SOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCLK, "SIPIX_XCLK");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDDO_10, "SIPIX_SHD_N");
- ret |= gpio_request(MX6SL_ARM2_EPDC_SDCE0, "SIPIX2_CE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE");
return ret;
}
static void spdc_put_pins(void)
{
- gpio_free(MX6SL_ARM2_EPDC_SDDO_0);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_1);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_2);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_3);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_4);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_5);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_6);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_7);
-
- gpio_free(MX6SL_ARM2_EPDC_GDOE);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_9);
- gpio_free(MX6SL_ARM2_EPDC_GDSP);
- gpio_free(MX6SL_ARM2_EPDC_GDCLK);
- gpio_free(MX6SL_ARM2_EPDC_SDSHR);
- gpio_free(MX6SL_ARM2_EPDC_SDLE);
- gpio_free(MX6SL_ARM2_EPDC_SDCE1);
- gpio_free(MX6SL_ARM2_EPDC_SDCLK);
- gpio_free(MX6SL_ARM2_EPDC_SDDO_10);
- gpio_free(MX6SL_ARM2_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
}
static void spdc_enable_pins(void)
{
/* Configure MUX settings to enable SPDC use */
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_spdc_enable_pads, \
- ARRAY_SIZE(mx6sl_arm2_spdc_enable_pads));
-
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_0);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_1);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_2);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_3);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_4);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_5);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_6);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_7);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDOE);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_9);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDSP);
- gpio_direction_input(MX6SL_ARM2_EPDC_GDCLK);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDSHR);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDLE);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCE1);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCLK);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDDO_10);
- gpio_direction_input(MX6SL_ARM2_EPDC_SDCE0);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
}
static void spdc_disable_pins(void)
{
/* Configure MUX settings for SPDC pins to
* GPIO and drive to 0. */
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_spdc_disable_pads, \
- ARRAY_SIZE(mx6sl_arm2_spdc_disable_pads));
-
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_0, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_1, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_2, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_3, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_4, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_5, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_6, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_7, 0);
-
- gpio_direction_output(MX6SL_ARM2_EPDC_GDOE, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_9, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDSP, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_GDCLK, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDSHR, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDLE, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCE1, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCLK, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDDO_10, 0);
- gpio_direction_output(MX6SL_ARM2_EPDC_SDCE0, 0);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
}
static struct imx_spdc_panel_init_set spdc_init_set = {
@@ -1105,9 +1051,9 @@ static void setup_spdc(void)
static void imx6_arm2_usbotg_vbus(bool on)
{
if (on)
- gpio_set_value(MX6_ARM2_USBOTG1_PWR, 1);
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 1);
else
- gpio_set_value(MX6_ARM2_USBOTG1_PWR, 0);
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 0);
}
static void __init mx6_arm2_init_usb(void)
@@ -1120,23 +1066,28 @@ static void __init mx6_arm2_init_usb(void)
* or it will affect signal quality at dp.
*/
- ret = gpio_request(MX6_ARM2_USBOTG1_PWR, "usbotg-pwr");
+ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr");
if (ret) {
- pr_err("failed to get GPIO MX6_ARM2_USBOTG1_PWR:%d\n", ret);
+ pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret);
return;
}
- gpio_direction_output(MX6_ARM2_USBOTG1_PWR, 0);
+ gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0);
- ret = gpio_request(MX6_ARM2_USBOTG2_PWR, "usbh1-pwr");
+ ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr");
if (ret) {
- pr_err("failed to get GPIO MX6_ARM2_USBOTG2_PWR:%d\n", ret);
+ pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret);
return;
}
- gpio_direction_output(MX6_ARM2_USBOTG2_PWR, 1);
+ gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1);
mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
mx6_usb_dr_init();
#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_DAT,
+ PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_STROBE,
+ PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK);
+
mx6_usb_h2_init();
#endif
}
@@ -1197,23 +1148,23 @@ static const struct matrix_keymap_data mx6sl_arm2_map_data __initconst = {
};
static void __init elan_ts_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_elan_pads,
- ARRAY_SIZE(mx6sl_arm2_elan_pads));
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads,
+ ARRAY_SIZE(mx6sl_brd_elan_pads));
/* ELAN Touchscreen */
- gpio_request(MX6SL_ARM2_ELAN_INT, "elan-interrupt");
- gpio_direction_input(MX6SL_ARM2_ELAN_INT);
+ gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(MX6SL_BRD_ELAN_INT);
- gpio_request(MX6SL_ARM2_ELAN_CE, "elan-cs");
- gpio_direction_output(MX6SL_ARM2_ELAN_CE, 1);
- gpio_direction_output(MX6SL_ARM2_ELAN_CE, 0);
+ gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs");
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 0);
- gpio_request(MX6SL_ARM2_ELAN_RST, "elan-rst");
- gpio_direction_output(MX6SL_ARM2_ELAN_RST, 1);
- gpio_direction_output(MX6SL_ARM2_ELAN_RST, 0);
+ gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst");
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 0);
mdelay(1);
- gpio_direction_output(MX6SL_ARM2_ELAN_RST, 1);
- gpio_direction_output(MX6SL_ARM2_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
}
#define SNVS_LPCR 0x38
@@ -1232,18 +1183,20 @@ static void mx6_snvs_poweroff(void)
*/
static void __init mx6_arm2_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(mx6sl_arm2_pads, ARRAY_SIZE(mx6sl_arm2_pads));
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
+ ARRAY_SIZE(mx6sl_brd_pads));
elan_ts_init();
- #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id;
- #else
+ soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id;
+#else
gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id;
soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id;
pu_reg_id = mx6sl_arm2_dvfscore_data.pu_id;
mx6_cpu_regulator_init();
- #endif
+#endif
imx6q_add_imx_snvs_rtc();
@@ -1285,8 +1238,8 @@ static void __init mx6_arm2_init(void)
imx6q_add_mxc_pwm_backlight(0, &mx6_arm2_pwm_backlight_data);
imx6dl_add_imx_elcdif(&fb_data[0]);
- gpio_request(MX6_ARM2_LCD_PWR_EN, "elcdif-power-on");
- gpio_direction_output(MX6_ARM2_LCD_PWR_EN, 1);
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
mxc_register_device(&lcd_wvga_device, NULL);
imx6dl_add_imx_pxp();
@@ -1309,6 +1262,11 @@ static void __init mx6_arm2_init(void)
imx6q_add_busfreq();
imx6sl_add_dcp();
imx6sl_add_rngb();
+ imx6sl_add_imx_pxp_v4l2();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
pm_power_off = mx6_snvs_poweroff;
}
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.h b/arch/arm/mach-mx6/board-mx6sl_common.h
index 09a211690029..d005e02cb6ac 100755..100644
--- a/arch/arm/mach-mx6/board-mx6sl_arm2.h
+++ b/arch/arm/mach-mx6/board-mx6sl_common.h
@@ -16,11 +16,68 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef _BOARD_MX6SL_ARM2_H
-#define _BOARD_MX6SL_ARM2_H
+#ifndef _BOARD_MX6SL_COMMON_H
+#define _BOARD_MX6SL_COMMON_H
#include <mach/iomux-mx6sl.h>
-static iomux_v3_cfg_t mx6sl_arm2_pads[] = {
+#define MX6_BRD_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */
+#define MX6_BRD_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */
+#define MX6_BRD_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */
+#define MX6_BRD_SD1_WP IMX_GPIO_NR(4, 6) /* KEY_COL7 */
+#define MX6_BRD_SD1_CD IMX_GPIO_NR(4, 7) /* KEY_ROW7 */
+#define MX6_BRD_ECSPI1_CS0 IMX_GPIO_NR(4, 11) /* ECSPI1_SS0 */
+#define MX6_BRD_HEADPHONE_DET IMX_GPIO_NR(4, 19) /* FEC_RX_ER */
+#define MX6_BRD_SD2_WP IMX_GPIO_NR(4, 29) /* SD2_DAT6 */
+#define MX6_BRD_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */
+#define MX6_BRD_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */
+#define MX6_BRD_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */
+
+/* EPDC GPIO pins */
+#define MX6SL_BRD_EPDC_SDDO_0 IMX_GPIO_NR(1, 7)
+#define MX6SL_BRD_EPDC_SDDO_1 IMX_GPIO_NR(1, 8)
+#define MX6SL_BRD_EPDC_SDDO_2 IMX_GPIO_NR(1, 9)
+#define MX6SL_BRD_EPDC_SDDO_3 IMX_GPIO_NR(1, 10)
+#define MX6SL_BRD_EPDC_SDDO_4 IMX_GPIO_NR(1, 11)
+#define MX6SL_BRD_EPDC_SDDO_5 IMX_GPIO_NR(1, 12)
+#define MX6SL_BRD_EPDC_SDDO_6 IMX_GPIO_NR(1, 13)
+#define MX6SL_BRD_EPDC_SDDO_7 IMX_GPIO_NR(1, 14)
+#define MX6SL_BRD_EPDC_SDDO_8 IMX_GPIO_NR(1, 15)
+#define MX6SL_BRD_EPDC_SDDO_9 IMX_GPIO_NR(1, 16)
+#define MX6SL_BRD_EPDC_SDDO_10 IMX_GPIO_NR(1, 17)
+#define MX6SL_BRD_EPDC_SDDO_11 IMX_GPIO_NR(1, 18)
+#define MX6SL_BRD_EPDC_SDDO_12 IMX_GPIO_NR(1, 19)
+#define MX6SL_BRD_EPDC_SDDO_13 IMX_GPIO_NR(1, 20)
+#define MX6SL_BRD_EPDC_SDDO_14 IMX_GPIO_NR(1, 21)
+#define MX6SL_BRD_EPDC_SDDO_15 IMX_GPIO_NR(1, 22)
+#define MX6SL_BRD_EPDC_GDCLK IMX_GPIO_NR(1, 31)
+#define MX6SL_BRD_EPDC_GDSP IMX_GPIO_NR(2, 2)
+#define MX6SL_BRD_EPDC_GDOE IMX_GPIO_NR(2, 0)
+#define MX6SL_BRD_EPDC_GDRL IMX_GPIO_NR(2, 1)
+#define MX6SL_BRD_EPDC_SDCLK IMX_GPIO_NR(1, 23)
+#define MX6SL_BRD_EPDC_SDOE IMX_GPIO_NR(1, 25)
+#define MX6SL_BRD_EPDC_SDLE IMX_GPIO_NR(1, 24)
+#define MX6SL_BRD_EPDC_SDSHR IMX_GPIO_NR(1, 26)
+#define MX6SL_BRD_EPDC_PWRCOM IMX_GPIO_NR(2, 11)
+#define MX6SL_BRD_EPDC_PWRSTAT IMX_GPIO_NR(2, 13)
+#define MX6SL_BRD_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 7)
+#define MX6SL_BRD_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 8)
+#define MX6SL_BRD_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 9)
+#define MX6SL_BRD_EPDC_PWRCTRL3 IMX_GPIO_NR(2, 10)
+#define MX6SL_BRD_EPDC_BDR0 IMX_GPIO_NR(2, 5)
+#define MX6SL_BRD_EPDC_BDR1 IMX_GPIO_NR(2, 6)
+#define MX6SL_BRD_EPDC_SDCE0 IMX_GPIO_NR(1, 27)
+#define MX6SL_BRD_EPDC_SDCE1 IMX_GPIO_NR(1, 28)
+#define MX6SL_BRD_EPDC_SDCE2 IMX_GPIO_NR(1, 29)
+#define MX6SL_BRD_EPDC_SDCE3 IMX_GPIO_NR(1, 30)
+#define MX6SL_BRD_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */
+#define MX6SL_BRD_EPDC_PMIC_INT IMX_GPIO_NR(2, 12) /* EPDC_PWRINT */
+#define MX6SL_BRD_EPDC_VCOM IMX_GPIO_NR(2, 3)
+/* ELAN TS */
+#define MX6SL_BRD_ELAN_CE IMX_GPIO_NR(2, 9)
+#define MX6SL_BRD_ELAN_INT IMX_GPIO_NR(2, 10)
+#define MX6SL_BRD_ELAN_RST IMX_GPIO_NR(4, 4)
+
+static iomux_v3_cfg_t mx6sl_brd_pads[] = {
/* AUDMUX */
MX6SL_PAD_AUD_TXC__AUDMUX_AUD3_TXC,
@@ -158,7 +215,7 @@ static iomux_v3_cfg_t mx6sl_arm2_pads[] = {
MX6SL_PAD_WDOG_B__WDOG1_WDOG_B,
};
-static iomux_v3_cfg_t mx6sl_arm2_epdc_enable_pads[] = {
+static iomux_v3_cfg_t mx6sl_brd_epdc_enable_pads[] = {
/* EPDC */
MX6SL_PAD_EPDC_D0__EPDC_SDDO_0,
MX6SL_PAD_EPDC_D1__EPDC_SDDO_1,
@@ -197,7 +254,7 @@ static iomux_v3_cfg_t mx6sl_arm2_epdc_enable_pads[] = {
MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
};
-static iomux_v3_cfg_t mx6sl_arm2_epdc_disable_pads[] = {
+static iomux_v3_cfg_t mx6sl_brd_epdc_disable_pads[] = {
/* EPDC */
MX6SL_PAD_EPDC_D0__GPIO_1_7,
MX6SL_PAD_EPDC_D1__GPIO_1_8,
@@ -236,7 +293,7 @@ static iomux_v3_cfg_t mx6sl_arm2_epdc_disable_pads[] = {
MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
};
-static iomux_v3_cfg_t mx6sl_arm2_spdc_enable_pads[] = {
+static iomux_v3_cfg_t mx6sl_brd_spdc_enable_pads[] = {
/* SPDC data*/
MX6SL_PAD_EPDC_D0__TCON_E_DATA_0,
MX6SL_PAD_EPDC_D1__TCON_E_DATA_1,
@@ -280,7 +337,7 @@ static iomux_v3_cfg_t mx6sl_arm2_spdc_enable_pads[] = {
MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
};
-static iomux_v3_cfg_t mx6sl_arm2_spdc_disable_pads[] = {
+static iomux_v3_cfg_t mx6sl_brd_spdc_disable_pads[] = {
MX6SL_PAD_EPDC_D0__GPIO_1_7,
MX6SL_PAD_EPDC_D1__GPIO_1_8,
MX6SL_PAD_EPDC_D2__GPIO_1_9,
@@ -315,7 +372,7 @@ static iomux_v3_cfg_t mx6sl_arm2_spdc_disable_pads[] = {
MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
};
-static iomux_v3_cfg_t mx6sl_arm2_elan_pads[] = {
+static iomux_v3_cfg_t mx6sl_brd_elan_pads[] = {
MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, /* INT */
MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, /* CE */
MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */
diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c
new file mode 100644
index 000000000000..81654a0c99fd
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_evk.c
@@ -0,0 +1,1320 @@
+/*
+ * 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 <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <sound/wm8962.h>
+#include <sound/pcm.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6sl.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6sl_common.h"
+
+
+static int spdc_sel;
+static int max17135_regulator_init(struct max17135 *max17135);
+struct clk *extern_audio_root;
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int __init mx6sl_evk_init_pfuze100(u32 int_gpio);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 0:
+ sd_pads_200mhz = mx6sl_sd1_200mhz;
+ sd_pads_100mhz = mx6sl_sd1_100mhz;
+ sd_pads_50mhz = mx6sl_sd1_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz);
+ break;
+ case 1:
+ sd_pads_200mhz = mx6sl_sd2_200mhz;
+ sd_pads_100mhz = mx6sl_sd2_100mhz;
+ sd_pads_50mhz = mx6sl_sd2_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz);
+ break;
+ case 2:
+ sd_pads_200mhz = mx6sl_sd3_200mhz;
+ sd_pads_100mhz = mx6sl_sd3_100mhz;
+ sd_pads_50mhz = mx6sl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz);
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6_evk_sd1_data __initconst = {
+ .cd_gpio = MX6_BRD_SD1_CD,
+ .wp_gpio = MX6_BRD_SD1_WP,
+ .support_8bit = 1,
+ .support_18v = 1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_evk_sd2_data __initconst = {
+ .cd_gpio = MX6_BRD_SD2_CD,
+ .wp_gpio = MX6_BRD_SD2_WP,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_evk_sd3_data __initconst = {
+ .cd_gpio = MX6_BRD_SD3_CD,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply evk_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+};
+
+static struct regulator_init_data evk_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(evk_vmmc_consumers),
+ .consumer_supplies = evk_vmmc_consumers,
+};
+
+static struct fixed_voltage_config evk_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &evk_vmmc_init,
+};
+
+static struct platform_device evk_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &evk_vmmc_reg_config,
+ },
+};
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static const struct anatop_thermal_platform_data
+ mx6sl_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+ };
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * TODO: We cannot enable full constraints for now, since
+ * it results in the PFUZE regulators being disabled
+ * at the end of boot, which disables critical regulators.
+ */
+ /*regulator_has_full_constraints();*/
+
+ return 0;
+}
+
+static int mx6_evk_spi_cs[] = {
+ MX6_BRD_ECSPI1_CS0,
+};
+
+static const struct spi_imx_master mx6_evk_spi_data __initconst = {
+ .chipselect = mx6_evk_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_evk_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+};
+#endif
+
+static void spi_device_init(void)
+{
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+#endif
+}
+
+static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data wm8962_data;
+
+static struct platform_device mx6_sabresd_audio_wm8962_device = {
+ .name = "imx-wm8962",
+};
+
+static struct wm8962_pdata wm8962_config_data = {
+
+};
+
+static int wm8962_clk_enable(int enable)
+{
+ if (enable)
+ clk_enable(extern_audio_root);
+ else
+ clk_disable(extern_audio_root);
+
+ return 0;
+}
+
+static int mxc_wm8962_init(void)
+{
+ struct clk *pll4;
+ int rate;
+
+ extern_audio_root = clk_get(NULL, "extern_audio_clk");
+ if (IS_ERR(extern_audio_root)) {
+ pr_err("can't get extern_audio_root clock.\n");
+ return PTR_ERR(extern_audio_root);
+ }
+
+ pll4 = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4)) {
+ pr_err("can't get pll4 clock.\n");
+ return PTR_ERR(pll4);
+ }
+
+ clk_set_parent(extern_audio_root, pll4);
+
+ rate = clk_round_rate(extern_audio_root, 26000000);
+ clk_set_rate(extern_audio_root, rate);
+
+ wm8962_data.sysclk = rate;
+ /* set AUDMUX pads to 1.8v */
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_MCLK,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_RXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXC,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXFS,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+
+ return 0;
+}
+
+static struct mxc_audio_platform_data wm8962_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = MX6_BRD_HEADPHONE_DET,
+ .hp_active_low = 1,
+ .mic_gpio = -1,
+ .mic_active_low = 1,
+ .init = mxc_wm8962_init,
+ .clock_enable = wm8962_clk_enable,
+};
+
+static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_init_data sabresd_vwm8962_init = {
+ .constraints = {
+ .name = "SPKVDD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers),
+ .consumer_supplies = sabresd_vwm8962_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vwm8962_reg_config = {
+ .supply_name = "SPKVDD",
+ .microvolts = 4325000,
+ .gpio = -1,
+ .enabled_at_boot = 1,
+ .init_data = &sabresd_vwm8962_init,
+};
+
+static struct platform_device sabresd_vwm8962_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &sabresd_vwm8962_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ platform_device_register(&sabresd_vwm8962_reg_devices);
+ mxc_register_device(&mx6_sabresd_audio_wm8962_device,
+ &wm8962_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ return 0;
+}
+
+static struct imxi2c_platform_data mx6_evk_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_evk_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_evk_i2c2_data = {
+ .bitrate = 400000,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0x48),
+ .platform_data = &max17135_pdata,
+ }, {
+ I2C_BOARD_INFO("elan-touch", 0x10),
+ .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT),
+ }, {
+ I2C_BOARD_INFO("mma8450", 0x1c),
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8962", 0x1a),
+ .platform_data = &wm8962_config_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ },
+};
+
+static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = {
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+#else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+#endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M,
+};
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+
+static inline void mx6_evk_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */
+}
+
+static int mx6sl_evk_fec_phy_init(struct phy_device *phydev)
+{
+ int val;
+
+ /* power on FEC phy and reset phy */
+ gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr");
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0);
+ /* wait RC ms for hw reset */
+ msleep(1);
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1);
+
+ /* check phy power */
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6sl_evk_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_GDRL);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_BDR0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDRL);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_BDR0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static int spdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for SPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE");
+
+ return ret;
+}
+
+static void spdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable SPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_disable_pins(void)
+{
+ /* Configure MUX settings for SPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+}
+
+static struct imx_spdc_panel_init_set spdc_init_set = {
+ .yoe_pol = false,
+ .dual_gate = false,
+ .resolution = 0,
+ .ud = false,
+ .rl = false,
+ .data_filter_n = true,
+ .power_ready = true,
+ .rgbw_mode_enable = false,
+ .hburst_len_en = true,
+};
+
+static struct fb_videomode erk_1_4_a01 = {
+ .name = "ERK_1_4_A01",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 40000000,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct imx_spdc_fb_mode spdc_panel_modes[] = {
+ {
+ &erk_1_4_a01,
+ &spdc_init_set,
+ .wave_timing = "pvi"
+ },
+};
+
+static struct imx_spdc_fb_platform_data spdc_data = {
+ .spdc_mode = spdc_panel_modes,
+ .num_modes = ARRAY_SIZE(spdc_panel_modes),
+ .get_pins = spdc_get_pins,
+ .put_pins = spdc_put_pins,
+ .enable_pins = spdc_enable_pins,
+ .disable_pins = spdc_disable_pins,
+};
+
+static int __init early_use_spdc_sel(char *p)
+{
+ spdc_sel = 1;
+ return 0;
+}
+early_param("spdc", early_use_spdc_sel);
+
+static void setup_spdc(void)
+{
+ /* GPR0[8]: 0:EPDC, 1:SPDC */
+ if (spdc_sel)
+ mxc_iomux_set_gpr_register(0, 8, 1, 1);
+}
+
+static void imx6_evk_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 1);
+ else
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 0);
+}
+
+static void __init mx6_evk_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0);
+
+ ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1);
+
+ mx6_set_otghost_vbus_func(imx6_evk_usbotg_vbus);
+ mx6_usb_dr_init();
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+#endif
+}
+
+static struct platform_pwm_backlight_data mx6_evk_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+static struct fb_videomode video_modes[] = {
+ {
+ /* 800x480 @ 57 Hz , pixel clk @ 32MHz */
+ "SEIKO-WVGA", 60, 800, 480, 29850, 99, 164, 33, 10, 10, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "SEIKO-WVGA",
+ .mode = video_modes,
+ .num_modes = ARRAY_SIZE(video_modes),
+ },
+};
+
+static struct platform_device lcd_wvga_device = {
+ .name = "lcd_seiko",
+};
+
+static int mx6sl_evk_keymap[] = {
+ KEY(0, 0, KEY_SELECT),
+ KEY(0, 1, KEY_BACK),
+ KEY(0, 2, KEY_F1),
+ KEY(0, 3, KEY_F2),
+
+ KEY(1, 0, KEY_F3),
+ KEY(1, 1, KEY_F4),
+ KEY(1, 2, KEY_F5),
+ KEY(1, 3, KEY_MENU),
+
+ KEY(2, 0, KEY_PREVIOUS),
+ KEY(2, 1, KEY_NEXT),
+ KEY(2, 2, KEY_HOME),
+ KEY(2, 3, KEY_NEXT),
+
+ KEY(3, 0, KEY_UP),
+ KEY(3, 1, KEY_LEFT),
+ KEY(3, 2, KEY_RIGHT),
+ KEY(3, 3, KEY_DOWN),
+};
+
+static const struct matrix_keymap_data mx6sl_evk_map_data __initconst = {
+ .keymap = mx6sl_evk_keymap,
+ .keymap_size = ARRAY_SIZE(mx6sl_evk_keymap),
+};
+static void __init elan_ts_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads,
+ ARRAY_SIZE(mx6sl_brd_elan_pads));
+
+ /* ELAN Touchscreen */
+ gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(MX6SL_BRD_ELAN_INT);
+
+ gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs");
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 0);
+
+ gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst");
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 0);
+ mdelay(1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+}
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+ u32 value;
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /* set TOP and DP_EN bit */
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_evk_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
+ ARRAY_SIZE(mx6sl_brd_pads));
+
+ elan_ts_init();
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ gp_reg_id = mx6sl_evk_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_evk_dvfscore_data.soc_id;
+#else
+ gp_reg_id = mx6sl_evk_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_evk_dvfscore_data.soc_id;
+ pu_reg_id = mx6sl_evk_dvfscore_data.pu_id;
+ mx6_cpu_regulator_init();
+#endif
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_i2c(0, &mx6_evk_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_evk_i2c1_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ imx6q_add_imx_i2c(2, &mx6_evk_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6_evk_spi_data);
+ spi_device_init();
+
+ mx6sl_evk_init_pfuze100(0);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data);
+
+ mx6_evk_init_uart();
+ /* get enet tx reference clk from FEC_REF_CLK pad.
+ * GPR1[14] = 0, GPR1[18:17] = 00
+ */
+ mxc_iomux_set_gpr_register(1, 14, 1, 0);
+ mxc_iomux_set_gpr_register(1, 17, 2, 0);
+
+ imx6_init_fec(fec_data);
+
+ platform_device_register(&evk_vmmc_reg_devices);
+ imx6q_add_sdhci_usdhc_imx(0, &mx6_evk_sd1_data);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6_evk_sd2_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_evk_sd3_data);
+
+ mx6_evk_init_usb();
+ imx6q_add_otp();
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_evk_pwm_backlight_data);
+ imx6dl_add_imx_elcdif(&fb_data[0]);
+
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ mxc_register_device(&lcd_wvga_device, NULL);
+
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+ mxc_register_device(&max17135_sensor_device, NULL);
+ setup_spdc();
+ if (!spdc_sel)
+ imx6dl_add_imx_epdc(&epdc_data);
+ else
+ imx6sl_add_imx_spdc(&spdc_data);
+ imx6q_add_dvfs_core(&mx6sl_evk_dvfscore_data);
+
+ imx6q_init_audio();
+
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6sl_add_imx_keypad(&mx6sl_evk_map_data);
+ imx6q_add_busfreq();
+ imx6sl_add_dcp();
+ imx6sl_add_rngb();
+ imx6sl_add_imx_pxp_v4l2();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+
+ pm_power_off = mx6_snvs_poweroff;
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6sl_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6_evk_reserve(void)
+{
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ phys_addr_t phys;
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+}
+
+MACHINE_START(MX6SL_EVK, "Freescale i.MX 6SoloLite EVK Board")
+ .boot_params = MX6SL_PHYS_OFFSET + 0x100,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_evk_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_evk_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c
index 9304c48361fa..151b4ee27eb6 100644
--- a/arch/arm/mach-mx6/bus_freq.c
+++ b/arch/arm/mach-mx6/bus_freq.c
@@ -47,12 +47,13 @@
#include <linux/suspend.h>
#define LPAPM_CLK 24000000
+#define DDR_AUDIO_CLK 50000000
#define DDR_MED_CLK 400000000
#define DDR3_NORMAL_CLK 528000000
#define GPC_PGC_GPU_PGCR_OFFSET 0x260
#define GPC_CNTR_OFFSET 0x0
-DEFINE_SPINLOCK(ddr_freq_lock);
+static DEFINE_SPINLOCK(freq_lock);
int low_bus_freq_mode;
int audio_bus_freq_mode;
@@ -69,18 +70,25 @@ int bus_freq_scaling_is_active;
int lp_high_freq;
int lp_med_freq;
int lp_audio_freq;
+int high_cpu_freq;
unsigned int ddr_low_rate;
unsigned int ddr_med_rate;
unsigned int ddr_normal_rate;
int low_freq_bus_used(void);
void set_ddr_freq(int ddr_freq);
+void *mx6sl_wfi_iram_base;
+void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr) = NULL;
+extern void mx6sl_wait (int arm_podf, unsigned long wfi_iram_addr);
+
+void *mx6sl_ddr_freq_base;
+void (*mx6sl_ddr_freq_change_iram)(int ddr_freq, int low_bus_freq_mode) = NULL;
+extern void mx6sl_ddr_iram(int ddr_freq);
extern int init_mmdc_settings(void);
extern struct cpu_op *(*get_cpu_op)(int *op);
extern int update_ddr_freq(int ddr_rate);
extern int chip_rev;
-extern bool arm_mem_clked_in_wait;
DEFINE_MUTEX(bus_freq_mutex);
@@ -88,6 +96,7 @@ struct timeval start_time;
struct timeval end_time;
static int cpu_op_nr;
+static u32 org_arm_podf;
static struct cpu_op *cpu_op_tbl;
static struct clk *pll2_400;
static struct clk *axi_clk;
@@ -97,18 +106,17 @@ static struct clk *osc_clk;
static struct clk *cpu_clk;
static struct clk *pll3;
static struct clk *pll2;
+static struct clk *pll1;
+static struct clk *pll1_sw_clk;
static struct clk *pll3_sw_clk;
static struct clk *pll2_200;
static struct clk *mmdc_ch0_axi;
-struct regulator *vddsoc_cap_regulator;
static struct clk *pll3_540;
static struct delayed_work low_bus_freq_handler;
static void reduce_bus_freq_handler(struct work_struct *work)
{
- int ret;
-
mutex_lock(&bus_freq_mutex);
if (low_bus_freq_mode || !low_freq_bus_used()) {
mutex_unlock(&bus_freq_mutex);
@@ -133,13 +141,13 @@ static void reduce_bus_freq_handler(struct work_struct *work)
if (lp_audio_freq) {
/* Need to ensure that PLL2_PFD_400M is kept ON. */
clk_enable(pll2_400);
- update_ddr_freq(50000000);
+ update_ddr_freq(DDR_AUDIO_CLK);
/* Make sure periph clk's parent also got updated */
clk_set_parent(periph_clk, pll2_200);
audio_bus_freq_mode = 1;
low_bus_freq_mode = 0;
} else {
- update_ddr_freq(24000000);
+ update_ddr_freq(LPAPM_CLK);
/* Make sure periph clk's parent also got updated */
clk_set_parent(periph_clk, osc_clk);
if (audio_bus_freq_mode)
@@ -154,43 +162,77 @@ static void reduce_bus_freq_handler(struct work_struct *work)
clk_disable(pll3);
med_bus_freq_mode = 0;
} else {
- /* Set VDDSOC_CAP to 1.1V */
- ret = regulator_set_voltage(vddsoc_cap_regulator, 1100000,
- 1100000);
- if (ret < 0) {
- printk(KERN_DEBUG
- "COULD NOT DECREASE VDDSOC_CAP VOLTAGE!!!!\n");
- return;
- }
-
- udelay(150);
+ u32 reg;
+ u32 div;
+ unsigned long flags;
- arm_mem_clked_in_wait = true;
+ spin_lock_irqsave(&freq_lock, flags);
- /* Set periph_clk to be sourced from OSC_CLK */
- /* Set MMDC clk to 25MHz. */
- /* First need to set the divider before changing the parent */
- /* if parent clock is larger than previous one */
- clk_set_rate(mmdc_ch0_axi, clk_get_rate(mmdc_ch0_axi) / 2);
- clk_set_parent(mmdc_ch0_axi, pll3_sw_clk);
- clk_set_parent(mmdc_ch0_axi, pll2_200);
- clk_set_rate(mmdc_ch0_axi,
- clk_round_rate(mmdc_ch0_axi, LPAPM_CLK));
-
- /* Set AXI to 24MHz. */
- clk_set_parent(periph_clk, osc_clk);
- clk_set_rate(axi_clk, clk_round_rate(axi_clk, LPAPM_CLK));
- /* Set AHB to 24MHz. */
- clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, LPAPM_CLK));
+ if (high_bus_freq_mode) {
+ /* Set periph_clk to be sourced from OSC_CLK */
+ /* Set AXI to 24MHz. */
+ clk_set_parent(periph_clk, osc_clk);
+ clk_set_rate(axi_clk,
+ clk_round_rate(axi_clk, LPAPM_CLK));
+ /* Set AHB to 24MHz. */
+ clk_set_rate(ahb_clk,
+ clk_round_rate(ahb_clk, LPAPM_CLK));
+ }
+ if (lp_audio_freq) {
+ /* PLL2 is on in this mode, as DDR is at 50MHz. */
+ /* Now change DDR freq while running from IRAM. */
+ mx6sl_ddr_freq_change_iram(DDR_AUDIO_CLK,
+ low_bus_freq_mode);
+
+ if (low_bus_freq_mode) {
+ /* Swtich ARM to run off PLL2_PFD2_400MHz
+ * since DDR is anway at 50MHz.
+ */
+ clk_set_parent(pll1_sw_clk, pll2_400);
+
+ /* Ensure that the clock will be
+ * at original speed.
+ */
+ reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ }
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 1;
+ } else {
+ /* Set MMDC clk to 24MHz. */
+ /* Since we are going to set PLL2 in bypass mode,
+ * move the CPU clock off PLL2.
+ */
+ /* Ensure that the clock will be at
+ * lowest possible freq.
+ */
+ org_arm_podf = __raw_readl(MXC_CCM_CACRR);
+ /* Need to enable PLL1 before setting its rate. */
+ clk_enable(pll1);
+ clk_set_rate(pll1,
+ cpu_op_tbl[cpu_op_nr - 1].pll_lpm_rate);
+ div = clk_get_rate(pll1) /
+ cpu_op_tbl[cpu_op_nr - 1].cpu_rate;
+
+ reg = __raw_writel(div - 1, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ clk_set_parent(pll1_sw_clk, pll1);
+
+ /* Now change DDR freq while running from IRAM. */
+ mx6sl_ddr_freq_change_iram(LPAPM_CLK,
+ low_bus_freq_mode);
- low_bus_freq_mode = 1;
- audio_bus_freq_mode = 0;
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ }
+ spin_unlock_irqrestore(&freq_lock, flags);
}
-
high_bus_freq_mode = 0;
- med_bus_freq_mode = 0;
mutex_unlock(&bus_freq_mutex);
}
+
/* Set the DDR, AHB to 24MHz.
* This mode will be activated only when none of the modules that
* need a higher DDR or AHB frequency are active.
@@ -215,61 +257,43 @@ int set_low_bus_freq(void)
*/
int set_high_bus_freq(int high_bus_freq)
{
- int ret;
-
if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
cancel_delayed_work_sync(&low_bus_freq_handler);
- mutex_lock(&bus_freq_mutex);
- if (busfreq_suspended) {
- mutex_unlock(&bus_freq_mutex);
+
+ if (busfreq_suspended)
return 0;
- }
- if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) {
- mutex_unlock(&bus_freq_mutex);
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
return 0;
- }
- if (high_bus_freq_mode && high_bus_freq) {
- mutex_unlock(&bus_freq_mutex);
+
+ if (high_bus_freq_mode && high_bus_freq)
return 0;
- }
- if (med_bus_freq_mode && !high_bus_freq) {
- mutex_unlock(&bus_freq_mutex);
+
+ /* medium bus freq is only supported for MX6DQ */
+ if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq)
return 0;
- }
if (cpu_is_mx6dl() && high_bus_freq)
high_bus_freq = 0;
- if (cpu_is_mx6dl() && med_bus_freq_mode) {
- mutex_unlock(&bus_freq_mutex);
+ if (cpu_is_mx6dl() && med_bus_freq_mode)
return 0;
- }
+
if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) ||
(med_bus_freq_mode && !high_bus_freq && lp_med_freq &&
- !lp_high_freq)) {
- mutex_unlock(&bus_freq_mutex);
+ !lp_high_freq))
return 0;
- }
+
if (cpu_is_mx6sl()) {
- /* Set the voltage of VDDSOC to 1.2V as in normal mode. */
- ret = regulator_set_voltage(vddsoc_cap_regulator, 1200000,
- 1200000);
- if (ret < 0) {
- printk(KERN_DEBUG
- "COULD NOT INCREASE VDDSOC_CAP VOLTAGE!!!!\n");
- return ret;
- }
+ u32 reg;
+ unsigned long flags;
- /* Need to wait for the regulator to come back up */
- /*
- * Delay time is based on the number of 24MHz clock cycles
- * programmed in the ANA_MISC2_BASE_ADDR for each
- * 25mV step.
- */
- udelay(150);
+ spin_lock_irqsave(&freq_lock, flags);
+ /* Change DDR freq in IRAM. */
+ mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode);
/* Set periph_clk to be sourced from pll2_pfd2_400M */
/* First need to set the divider before changing the */
@@ -280,17 +304,20 @@ int set_high_bus_freq(int high_bus_freq)
clk_round_rate(axi_clk, LPAPM_CLK / 2));
clk_set_parent(periph_clk, pll2_400);
- /* Set mmdc_clk_root to be sourced */
- /* from pll2_pfd2_400M */
- clk_set_rate(mmdc_ch0_axi,
- clk_round_rate(mmdc_ch0_axi, LPAPM_CLK / 2));
- clk_set_parent(mmdc_ch0_axi, pll3_sw_clk);
- clk_set_parent(mmdc_ch0_axi, pll2_400);
- clk_set_rate(mmdc_ch0_axi,
- clk_round_rate(mmdc_ch0_axi, DDR_MED_CLK));
+ if (low_bus_freq_mode) {
+ /* Now move ARM to be sourced from PLL2_400 too. */
+ clk_set_parent(pll1_sw_clk, pll2_400);
+ /* Ensure that the clock will be at original speed. */
+ reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ clk_disable(pll1);
+ }
high_bus_freq_mode = 1;
- med_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ spin_unlock_irqrestore(&freq_lock, flags);
} else {
clk_enable(pll3);
if (high_bus_freq) {
@@ -317,18 +344,11 @@ int set_high_bus_freq(int high_bus_freq)
clk_get_parent(axi_clk) != pll3_540)
clk_set_parent(axi_clk, pll3_540);
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+
clk_disable(pll3);
}
-
- low_bus_freq_mode = 0;
- audio_bus_freq_mode = 0;
-
- /* Ensure that WAIT mode can be entered in high bus freq mode. */
-
- if (cpu_is_mx6sl())
- arm_mem_clked_in_wait = false;
-
- mutex_unlock(&bus_freq_mutex);
return 0;
}
@@ -340,11 +360,8 @@ int low_freq_bus_used(void)
/* We only go the lowest setpoint if ARM is also
* at the lowest setpoint.
*/
- if ((clk_get_rate(cpu_clk) >
- cpu_op_tbl[cpu_op_nr - 1].cpu_rate)
- || (cpu_op_nr == 1)) {
+ if (high_cpu_freq)
return 0;
- }
if ((lp_high_freq == 0)
&& (lp_med_freq == 0))
@@ -356,62 +373,80 @@ int low_freq_bus_used(void)
void bus_freq_update(struct clk *clk, bool flag)
{
mutex_lock(&bus_freq_mutex);
+
if (flag) {
- /* Update count */
- if (clk->flags & AHB_HIGH_SET_POINT)
- lp_high_freq++;
- else if (clk->flags & AHB_MED_SET_POINT)
- lp_med_freq++;
- else if (clk->flags & AHB_AUDIO_SET_POINT)
- lp_audio_freq++;
- /* Update bus freq */
- if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
- && (clk_get_usecount(clk) == 0)) {
- if (!(clk->flags &
- (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) {
- if (low_freq_bus_used()) {
- if ((clk->flags & AHB_AUDIO_SET_POINT) & !audio_bus_freq_mode)
- set_low_bus_freq();
- else if (!low_bus_freq_mode)
- set_low_bus_freq();
- }
- } else {
- if ((clk->flags & AHB_MED_SET_POINT)
- && !med_bus_freq_mode) {
- /* Set to Medium setpoint */
- mutex_unlock(&bus_freq_mutex);
+ if (clk == cpu_clk) {
+ /* The CPU freq is being increased.
+ * check if we need to increase the bus freq
+ */
+ high_cpu_freq = 1;
+ if (low_bus_freq_mode || audio_bus_freq_mode)
set_high_bus_freq(0);
- return;
- }
- else if ((clk->flags & AHB_HIGH_SET_POINT)
- && !high_bus_freq_mode) {
- /* Currently at low or medium set point,
- * need to set to high setpoint
- */
- mutex_unlock(&bus_freq_mutex);
- set_high_bus_freq(1);
- return;
- }
+ } else {
+ /* Update count */
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq++;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq++;
+ else if (clk->flags & AHB_AUDIO_SET_POINT)
+ lp_audio_freq++;
+ /* Update bus freq */
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 0)) {
+ if (!(clk->flags &
+ (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) {
+ if (low_freq_bus_used()) {
+ if ((clk->flags & AHB_AUDIO_SET_POINT) &
+ !audio_bus_freq_mode)
+ set_low_bus_freq();
+ else if (!low_bus_freq_mode)
+ set_low_bus_freq();
+ }
+ } else {
+ if ((clk->flags & AHB_MED_SET_POINT)
+ && !med_bus_freq_mode) {
+ /* Set to Medium setpoint */
+ set_high_bus_freq(0);
+ } else if ((clk->flags & AHB_HIGH_SET_POINT)
+ && !high_bus_freq_mode) {
+ /* Currently at low or medium
+ * set point, need to set to
+ * high setpoint
+ */
+ set_high_bus_freq(1);
+ }
+ }
}
}
} else {
- /* Update count */
- if (clk->flags & AHB_HIGH_SET_POINT)
- lp_high_freq--;
- else if (clk->flags & AHB_MED_SET_POINT)
- lp_med_freq--;
- else if (clk->flags & AHB_AUDIO_SET_POINT)
- lp_audio_freq--;
- /* Update bus freq */
- if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
- && (clk_get_usecount(clk) == 0)) {
- if (low_freq_bus_used() && !low_bus_freq_mode)
+ if (clk == cpu_clk) {
+ /* CPU freq is dropped, check if we can
+ * lower the bus freq.
+ */
+ high_cpu_freq = 0;
+
+ if (low_freq_bus_used() &&
+ !(low_bus_freq_mode || audio_bus_freq_mode))
set_low_bus_freq();
- else {
- /* Set to either high or medium setpoint. */
- mutex_unlock(&bus_freq_mutex);
- set_high_bus_freq(0);
- return;
+ } else {
+ /* Update count */
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq--;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq--;
+ else if (clk->flags & AHB_AUDIO_SET_POINT)
+ lp_audio_freq--;
+ /* Update bus freq */
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 0)) {
+ if (low_freq_bus_used())
+ set_low_bus_freq();
+ else {
+ /* Set to either high or
+ * medium setpoint.
+ */
+ set_high_bus_freq(0);
+ }
}
}
}
@@ -436,7 +471,15 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev,
const char *buf, size_t size)
{
if (strncmp(buf, "1", 1) == 0) {
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q())
+ /*do not enable bus freq*/
+ bus_freq_scaling_is_active = 0;
+ printk(KERN_WARNING "Bus frequency can't be enabled if using VPU 352M!\n");
+ return size;
+#else
bus_freq_scaling_is_active = 1;
+#endif
set_high_bus_freq(0);
/* Make sure system can enter low bus mode if it should be in
low bus mode */
@@ -458,6 +501,8 @@ static int busfreq_suspend(struct platform_device *pdev, pm_message_t message)
static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
void *dummy)
{
+ mutex_lock(&bus_freq_mutex);
+
if (event == PM_SUSPEND_PREPARE) {
set_high_bus_freq(1);
busfreq_suspended = 1;
@@ -465,6 +510,8 @@ static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
busfreq_suspended = 0;
}
+ mutex_unlock(&bus_freq_mutex);
+
return NOTIFY_OK;
}
static int busfreq_resume(struct platform_device *pdev)
@@ -486,6 +533,7 @@ static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
* @return The function returns 0 on success
*
*/
+
static int __devinit busfreq_probe(struct platform_device *pdev)
{
u32 err;
@@ -513,6 +561,28 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
return PTR_ERR(pll2);
}
+ pll1 = clk_get(NULL, "pll1_main_clk");
+ if (IS_ERR(pll1)) {
+ printk(KERN_DEBUG "%s: failed to get pll1\n",
+ __func__);
+ return PTR_ERR(pll1);
+ }
+
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (IS_ERR(pll1_sw_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n",
+ __func__);
+ return PTR_ERR(pll1_sw_clk);
+ }
+
+
+ if (IS_ERR(pll2)) {
+ printk(KERN_DEBUG "%s: failed to get pll2\n",
+ __func__);
+ return PTR_ERR(pll2);
+ }
+
+
cpu_clk = clk_get(NULL, "cpu_clk");
if (IS_ERR(cpu_clk)) {
printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
@@ -576,13 +646,6 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
return PTR_ERR(mmdc_ch0_axi);
}
- vddsoc_cap_regulator = regulator_get(NULL, "cpu_vddsoc");
- if (IS_ERR(vddsoc_cap_regulator)) {
- printk(KERN_ERR "%s: failed to get vddsoc_cap regulator\n",
- __func__);
- return PTR_ERR(vddsoc_cap_regulator);
- }
-
err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
if (err) {
printk(KERN_ERR
@@ -598,6 +661,11 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
/* To make pll2_400 use count right, as when
system enter 24M, it will disable pll2_400 */
clk_enable(pll2_400);
+ } else if (cpu_is_mx6sl()) {
+ /* Set med_bus_freq_mode to 1 since med_bus_freq_mode
+ is not supported as yet for MX6SL */
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 1;
} else {
high_bus_freq_mode = 1;
med_bus_freq_mode = 0;
@@ -620,6 +688,33 @@ static int __devinit busfreq_probe(struct platform_device *pdev)
if (!cpu_is_mx6sl())
init_mmdc_settings();
+ else {
+ unsigned long iram_paddr;
+
+ /* Allocate IRAM for WFI code when system is
+ * in low freq mode.
+ */
+ iram_alloc(SZ_4K, &iram_paddr);
+ /* Need to remap the area here since we want
+ * the memory region to be executable.
+ */
+ mx6sl_wfi_iram_base = __arm_ioremap(iram_paddr,
+ SZ_4K, MT_MEMORY_NONCACHED);
+ memcpy(mx6sl_wfi_iram_base, mx6sl_wait, SZ_4K);
+ mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base;
+
+ /* Allocate IRAM for WFI code when system is
+ *in low freq mode.
+ */
+ iram_alloc(SZ_4K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ mx6sl_ddr_freq_base = __arm_ioremap(iram_paddr,
+ SZ_4K, MT_MEMORY_NONCACHED);
+ memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, SZ_4K);
+ mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base;
+
+ }
return 0;
}
@@ -648,19 +743,19 @@ static int __init busfreq_init(void)
printk(KERN_INFO "Bus freq driver module loaded\n");
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q())
+ bus_freq_scaling_is_active = 0;/*disable bus_freq*/
+
+#else
/* Enable busfreq by default. */
bus_freq_scaling_is_active = 1;
-
+#endif
if (cpu_is_mx6q())
set_high_bus_freq(1);
- else
+ else if (cpu_is_mx6dl())
set_high_bus_freq(0);
- /* Make sure system can enter low bus mode if it should be in
- low bus mode */
- if (low_freq_bus_used() && !low_bus_freq_mode)
- set_low_bus_freq();
-
printk(KERN_INFO "Bus freq driver Enabled\n");
return 0;
}
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 86587b5eb2e2..80781a6869ad 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -472,7 +472,6 @@ static int _clk_pll_enable(struct clk *clk)
pllbase = _get_pll_base(clk);
reg = __raw_readl(pllbase);
- reg &= ~ANADIG_PLL_BYPASS;
reg &= ~ANADIG_PLL_POWER_DOWN;
/* The 480MHz PLLs have the opposite definition for power bit. */
@@ -492,6 +491,7 @@ static int _clk_pll_enable(struct clk *clk)
/* Enable the PLL output now*/
reg = __raw_readl(pllbase);
+ reg &= ~ANADIG_PLL_BYPASS;
reg |= ANADIG_PLL_ENABLE;
__raw_writel(reg, pllbase);
@@ -505,6 +505,15 @@ static void _clk_pll_disable(struct clk *clk)
if ((arm_needs_pll2_400) && (clk == &pll2_528_bus_main_clk))
return;
+ /*
+ * To support USB remote wake up, need always keep power and enable bit
+ * BM_ANADIG_ANA_MISC2_CONTROL0 will power off PLL3's power
+ * Please see TKT064178 for detail.
+ */
+ if (clk == &pll3_usb_otg_main_clk) {
+ __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET);
+ return;
+ }
pllbase = _get_pll_base(clk);
@@ -514,12 +523,6 @@ static void _clk_pll_disable(struct clk *clk)
__raw_writel(reg, pllbase);
- /*
- * It will power off PLL3's power, it is the TO1.1 fix
- * Please see TKT064178 for detail.
- */
- if (clk == &pll3_usb_otg_main_clk)
- __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET);
}
static unsigned long _clk_pll1_main_get_rate(struct clk *clk)
@@ -1258,15 +1261,27 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
* PLL2_PFD_400M.
*/
if (pll1_sw_clk.parent != &pll2_pfd_400M) {
- pll2_pfd_400M.enable(&pll2_pfd_400M);
+ if (pll2_pfd_400M.usecount == 0) {
+ /* Check if PLL2 needs to be enabled also. */
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk);
+ /* Ensure parent usecount is
+ * also incremented.
+ */
+ pll2_528_bus_main_clk.usecount++;
+ pll2_pfd_400M.enable(&pll2_pfd_400M);
+ }
+ pll2_pfd_400M.usecount++;
arm_needs_pll2_400 = true;
pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
pll1_sw_clk.parent = &pll2_pfd_400M;
}
} else {
/* Make sure PLL1 is enabled */
- if (!pll1_enabled)
+ if (!pll1_enabled) {
pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 1;
+ }
/* Make sure PLL1 rate is what we want */
if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
/* If pll1_sw_clk is from pll1_sys_main_clk, switch it */
@@ -1282,9 +1297,19 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
/* Make sure pll1_sw_clk is from pll1_sys_main_clk */
pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
pll1_sw_clk.parent = &pll1_sys_main_clk;
+ if (arm_needs_pll2_400) {
+ pll2_pfd_400M.usecount--;
+ if (pll2_pfd_400M.usecount == 0) {
+ pll2_pfd_400M.disable(&pll2_pfd_400M);
+ /* Ensure parent usecount is
+ * also decremented.
+ */
+ pll2_528_bus_main_clk.usecount--;
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk);
+ }
+ }
arm_needs_pll2_400 = false;
- if (pll2_pfd_400M.usecount == 0)
- pll2_pfd_400M.disable(&pll2_pfd_400M);
}
parent_rate = clk_get_rate(clk->parent);
div = parent_rate / rate;
@@ -1320,8 +1345,10 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
while (__raw_readl(MXC_CCM_CDHIPR))
;
- if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400)
+ if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) {
pll1_sys_main_clk.disable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 0;
+ }
spin_unlock_irqrestore(&clk_lock, flags);
@@ -5301,6 +5328,8 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
{
__iomem void *base;
int i, reg;
+ u32 parent_rate, rate;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
external_low_reference = ckil;
external_high_reference = ckih1;
@@ -5336,6 +5365,12 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_tree_init();
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q()) {
+ clk_set_rate(&pll2_pfd_400M, 352000000);
+ clk_set_parent(&vpu_clk[0], &pll2_pfd_400M);
+ }
+#endif
/* keep correct count. */
clk_enable(&cpu_clk);
clk_enable(&periph_clk);
@@ -5504,6 +5539,20 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
lp_med_freq = 0;
lp_audio_freq = 0;
+ /* Get current ARM_PODF value */
+ rate = clk_get_rate(&cpu_clk);
+ parent_rate = clk_get_rate(&pll1_sw_clk);
+ cur_arm_podf = parent_rate / rate;
+
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state.
+ * The max ARM clk is decided by the ipg_clk and has to
+ * follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
/* Turn OFF all unnecessary PHYs. */
if (cpu_is_mx6q()) {
/* Turn off SATA PHY. */
diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c
index 3b2d9e527625..9742db4907f5 100755
--- a/arch/arm/mach-mx6/clock_mx6sl.c
+++ b/arch/arm/mach-mx6/clock_mx6sl.c
@@ -67,6 +67,7 @@ static struct clk pll7_usb_host_main_clk;
static struct clk usdhc3_clk;
static struct clk ipg_clk;
static struct clk gpt_clk[];
+static struct clk ahb_clk;
static struct cpu_op *cpu_op_tbl;
static int cpu_op_nr;
@@ -100,7 +101,9 @@ DEFINE_SPINLOCK(mx6sl_clk_lock);
u32 gpt_ticks; \
u32 gpt_cnt; \
u32 reg; \
+ unsigned long flags; \
int result = 1; \
+ spin_lock_irqsave(&mx6sl_clk_lock, flags); \
gpt_rate = clk_get_rate(&gpt_clk[0]); \
gpt_ticks = timeout / (1000000000 / gpt_rate); \
reg = __raw_readl(timer_base + V2_TSTAT);\
@@ -130,6 +133,7 @@ DEFINE_SPINLOCK(mx6sl_clk_lock);
} \
} \
} \
+ spin_unlock_irqrestore(&mx6sl_clk_lock, flags); \
result; \
})
@@ -409,6 +413,7 @@ static int _clk_pfd_enable(struct clk *clk)
__raw_writel((1 << (clk->enable_shift + 7)),
(int)clk->enable_reg + 8);
+ udelay(3);
return 0;
}
@@ -427,7 +432,6 @@ static int _clk_pll_enable(struct clk *clk)
pllbase = _get_pll_base(clk);
reg = __raw_readl(pllbase);
- reg &= ~ANADIG_PLL_BYPASS;
reg &= ~ANADIG_PLL_POWER_DOWN;
/* The 480MHz PLLs have the opposite definition for power bit. */
@@ -447,6 +451,7 @@ static int _clk_pll_enable(struct clk *clk)
/* Enable the PLL output now*/
reg = __raw_readl(pllbase);
+ reg &= ~ANADIG_PLL_BYPASS;
reg |= ANADIG_PLL_ENABLE;
__raw_writel(reg, pllbase);
@@ -466,7 +471,18 @@ static void _clk_pll_disable(struct clk *clk)
reg = __raw_readl(pllbase);
reg |= ANADIG_PLL_BYPASS;
- reg &= ~ANADIG_PLL_ENABLE;
+ reg |= ANADIG_PLL_POWER_DOWN;
+
+ /* The 480MHz PLLs have the opposite definition for power bit. */
+ if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk)
+ reg &= ~ANADIG_PLL_POWER_DOWN;
+
+ /* PLL1, PLL2, PLL3, PLL7 should not disable the ENABLE bit.
+ * The output of these PLLs maybe used even if they are bypassed.
+ */
+ if (clk == &pll4_audio_main_clk || clk == &pll5_video_main_clk ||
+ clk == &pll6_enet_main_clk)
+ reg &= ~ANADIG_PLL_ENABLE;
__raw_writel(reg, pllbase);
@@ -505,7 +521,7 @@ static int _clk_pll1_main_set_rate(struct clk *clk, unsigned long rate)
/* Wait for PLL1 to lock */
if (!WAIT((__raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_LOCK),
SPIN_DELAY))
- panic("pll1 enable failed\n");
+ panic("pll1 set rate failed\n");
return 0;
}
@@ -531,8 +547,7 @@ static void _clk_pll1_main_disable(struct clk *clk)
* requires PLL1 to be enabled.
*/
reg = __raw_readl(pllbase);
- reg |= ANADIG_PLL_BYPASS;
-
+ reg |= (ANADIG_PLL_BYPASS | ANADIG_PLL_POWER_DOWN);
__raw_writel(reg, pllbase);
}
@@ -1140,6 +1155,11 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
if (i >= cpu_op_nr)
return -EINVAL;
+ if (clk_get_rate(&ahb_clk) == 24000000) {
+ printk(KERN_INFO "we should not be here!!!!! AHB is at 24MHz....cpu_rate requested = %ld\n", rate);
+ dump_stack();
+ BUG();
+ }
spin_lock_irqsave(&mx6sl_clk_lock, flags);
if (rate <= clk_get_rate(&pll2_pfd2_400M)) {
@@ -1147,15 +1167,27 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
* PLL2_PFD2_400M.
*/
if (pll1_sw_clk.parent != &pll2_pfd2_400M) {
- pll2_pfd2_400M.enable(&pll2_pfd2_400M);
+ if (pll2_pfd2_400M.usecount == 0) {
+ /* Check if PLL2 needs to be enabled also. */
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk);
+ /* Ensure parent usecount is
+ * also incremented.
+ */
+ pll2_528_bus_main_clk.usecount++;
+ pll2_pfd2_400M.enable(&pll2_pfd2_400M);
+ }
arm_needs_pll2_400 = true;
+ pll2_pfd2_400M.usecount++;
pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M);
pll1_sw_clk.parent = &pll2_pfd2_400M;
}
} else {
/* Make sure PLL1 is enabled */
- if (!pll1_enabled)
+ if (!pll1_enabled) {
pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 1;
+ }
if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
if (pll1_sw_clk.parent == &pll1_sys_main_clk) {
/* Change the PLL1 rate. */
@@ -1173,9 +1205,20 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
}
pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
pll1_sw_clk.parent = &pll1_sys_main_clk;
+
+ if (arm_needs_pll2_400) {
+ pll2_pfd2_400M.usecount--;
+ if (pll2_pfd2_400M.usecount == 0) {
+ pll2_pfd2_400M.disable(&pll2_pfd2_400M);
+ /* Ensure parent usecount is
+ * also decremented.
+ */
+ pll2_528_bus_main_clk.usecount--;
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk);
+ }
+ }
arm_needs_pll2_400 = false;
- if (pll2_pfd2_400M.usecount == 0)
- pll2_pfd2_400M.disable(&pll2_pfd2_400M);
}
parent_rate = clk_get_rate(clk->parent);
div = parent_rate / rate;
@@ -1211,8 +1254,10 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
while (__raw_readl(MXC_CCM_CDHIPR))
;
- if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400)
+ if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) {
pll1_sys_main_clk.disable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 0;
+ }
spin_unlock_irqrestore(&mx6sl_clk_lock, flags);
@@ -1266,7 +1311,7 @@ static int _clk_periph_set_parent(struct clk *clk, struct clk *parent)
reg &= ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
reg |= mux << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
__raw_writel(reg, MXC_CCM_CBCMR);
-
+ udelay(5);
/* Set the periph_clk_sel multiplexer. */
reg = __raw_readl(MXC_CCM_CBCDR);
reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
@@ -1433,6 +1478,7 @@ static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
div = parent_rate / rate;
if (div == 0)
div++;
+
if (((parent_rate / div) != rate) || (div > 8))
return -EINVAL;
@@ -2080,6 +2126,7 @@ static struct clk usdhc1_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc1_set_rate,
.get_rate = _clk_usdhc1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc2_set_parent(struct clk *clk, struct clk *parent)
@@ -2137,6 +2184,7 @@ static struct clk usdhc2_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc2_set_rate,
.get_rate = _clk_usdhc2_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc3_set_parent(struct clk *clk, struct clk *parent)
@@ -2195,6 +2243,7 @@ static struct clk usdhc3_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc3_set_rate,
.get_rate = _clk_usdhc3_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static int _clk_usdhc4_set_parent(struct clk *clk, struct clk *parent)
@@ -2253,6 +2302,7 @@ static struct clk usdhc4_clk = {
.round_rate = _clk_usdhc_round_rate,
.set_rate = _clk_usdhc4_set_rate,
.get_rate = _clk_usdhc4_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_ssi_round_rate(struct clk *clk,
@@ -2424,7 +2474,7 @@ static struct clk ssi1_clk = {
#else
.secondary = &mmdc_ch1_axi_clk[0],
#endif
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_ssi2_get_rate(struct clk *clk)
@@ -2498,7 +2548,7 @@ static struct clk ssi2_clk = {
#else
.secondary = &mmdc_ch1_axi_clk[0],
#endif
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_ssi3_get_rate(struct clk *clk)
@@ -2571,7 +2621,7 @@ static struct clk ssi3_clk = {
#else
.secondary = &mmdc_ch1_axi_clk[0],
#endif
- .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_epdc_lcdif_pix_round_rate(struct clk *clk,
@@ -2908,7 +2958,7 @@ static struct clk lcdif_pix_clk = {
.set_rate = _clk_lcdif_pix_set_rate,
.round_rate = _clk_epdc_lcdif_pix_round_rate,
.get_rate = _clk_lcdif_pix_get_rate,
- .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static struct clk epdc_pix_clk = {
@@ -2923,7 +2973,7 @@ static struct clk epdc_pix_clk = {
.set_rate = _clk_epdc_pix_set_rate,
.round_rate = _clk_epdc_lcdif_pix_round_rate,
.get_rate = _clk_epdc_pix_get_rate,
- .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
};
static unsigned long _clk_spdif_round_rate(struct clk *clk,
unsigned long rate)
@@ -3321,6 +3371,10 @@ static unsigned long _clk_uart_get_rate(struct clk *clk)
div = (reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
val = clk_get_rate(clk->parent) / div;
+ /* If the parent is OSC, there is an in-built divide by 6. */
+ if (clk->parent == &osc_clk)
+ val = val / 6;
+
return val;
}
@@ -3335,7 +3389,7 @@ static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
else
mux = 0; /* osc */
- reg |= mux << MXC_CCM_CSCDR2_ECSPI_CLK_SEL_OFFSET;
+ reg |= mux << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET;
__raw_writel(reg, MXC_CCM_CSCDR1);
@@ -3960,6 +4014,8 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
unsigned long ckih1, unsigned long ckih2)
{
int i;
+ u32 parent_rate, rate;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
external_low_reference = ckil;
external_high_reference = ckih1;
@@ -3978,6 +4034,12 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
* should be from OSC24M */
clk_set_parent(&ipg_perclk, &osc_clk);
+ /* Need to set IPG_PERCLK to 3MHz, so that we can
+ * satisfy the 2.5:1 AHB:IPG_PERCLK ratio. Since AHB
+ * can be dropped to as low as 8MHz in low power mode.
+ */
+ clk_set_rate(&ipg_perclk, 3000000);
+
gpt_clk[0].parent = &ipg_perclk;
gpt_clk[0].get_rate = NULL;
@@ -4024,7 +4086,6 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
} else {
__raw_writel(1 << MXC_CCM_CCGRx_CG11_OFFSET |
- 3 << MXC_CCM_CCGRx_CG2_OFFSET |
3 << MXC_CCM_CCGRx_CG1_OFFSET |
3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
}
@@ -4032,9 +4093,9 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1);
__raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET |
1 << MXC_CCM_CCGRx_CG11_OFFSET |
- 3 << MXC_CCM_CCGRx_CG10_OFFSET |
- 3 << MXC_CCM_CCGRx_CG9_OFFSET |
- 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
+ 1 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
__raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET |
3 << MXC_CCM_CCGRx_CG13_OFFSET |
3 << MXC_CCM_CCGRx_CG12_OFFSET |
@@ -4067,6 +4128,20 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
lp_high_freq = 0;
lp_med_freq = 0;
+ /* Get current ARM_PODF value */
+ rate = clk_get_rate(&cpu_clk);
+ parent_rate = clk_get_rate(&pll1_sw_clk);
+ cur_arm_podf = parent_rate / rate;
+
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state.
+ * The max ARM clk is decided by the ipg_clk and has to
+ * follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
return 0;
}
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
index b8d06e2ad09a..7e054c1d743c 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.c
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -24,70 +24,127 @@ extern u32 arm_max_freq;
static int num_cpu_op;
/* working point(wp): 0 - 1.2GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */
-static struct cpu_op mx6_cpu_op_1_2G[] = {
+static struct cpu_op mx6q_cpu_op_1_2G[] = {
{
.pll_rate = 1200000000,
.cpu_rate = 1200000000,
.cpu_podf = 0,
- .pu_voltage = 1250000,
- .soc_voltage = 1250000,
+ .pu_voltage = 1275000,
+ .soc_voltage = 1275000,
.cpu_voltage = 1275000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1100000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 925000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
};
/* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */
-static struct cpu_op mx6_cpu_op_1G[] = {
+static struct cpu_op mx6q_cpu_op_1G[] = {
{
.pll_rate = 996000000,
.cpu_rate = 996000000,
.cpu_podf = 0,
- .pu_voltage = 1200000,
- .soc_voltage = 1200000,
- .cpu_voltage = 1225000,},
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 1250000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1100000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 925000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
};
-static struct cpu_op mx6_cpu_op[] = {
+static struct cpu_op mx6q_cpu_op[] = {
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1100000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 925000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
};
/* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */
@@ -96,23 +153,23 @@ static struct cpu_op mx6dl_cpu_op_1_2G[] = {
.pll_rate = 1200000000,
.cpu_rate = 1200000000,
.cpu_podf = 0,
- .pu_voltage = 1250000,
- .soc_voltage = 1250000,
+ .pu_voltage = 1275000,
+ .soc_voltage = 1275000,
.cpu_voltage = 1275000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1100000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1150000,},
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1025000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
};
/* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */
static struct cpu_op mx6dl_cpu_op_1G[] = {
@@ -120,39 +177,98 @@ static struct cpu_op mx6dl_cpu_op_1G[] = {
.pll_rate = 996000000,
.cpu_rate = 996000000,
.cpu_podf = 0,
- .pu_voltage = 1200000,
- .soc_voltage = 1200000,
- .cpu_voltage = 1225000,},
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 1250000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1100000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1150000,},
{
.pll_rate = 396000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1025000,},
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
};
static struct cpu_op mx6dl_cpu_op[] = {
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
.cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1150000,},
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
+};
+
+static struct cpu_op mx6sl_cpu_op_1G[] = {
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1225000,
+ .soc_voltage = 1225000,
+ .cpu_voltage = 1275000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
.pu_voltage = 1150000,
.soc_voltage = 1150000,
+ .cpu_voltage = 1200000,},
+ {
+ .pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1050000,
+ .soc_voltage = 1050000,
.cpu_voltage = 1100000,},
{
.pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
+ .cpu_rate = 198000000,
+ .cpu_podf = 1,
+ .pu_voltage = 1050000,
+ .soc_voltage = 1050000,
+ .cpu_voltage = 1050000,},
+};
+
+static struct cpu_op mx6sl_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1150000,
+ .soc_voltage = 1150000,
+ .cpu_voltage = 1200000,},
+ {
+ .pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
.cpu_rate = 396000000,
.cpu_podf = 0,
- .pu_voltage = 1150000,
- .soc_voltage = 1150000,
- .cpu_voltage = 1025000,},
+ .pu_voltage = 1050000,
+ .soc_voltage = 1050000,
+ .cpu_voltage = 1100000,},
+ {
+ .pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
+ .cpu_rate = 198000000,
+ .cpu_podf = 1,
+ .pu_voltage = 1050000,
+ .soc_voltage = 1050000,
+ .cpu_voltage = 1050000,},
};
static struct dvfs_op dvfs_core_setpoint_1_2G[] = {
@@ -201,16 +317,24 @@ struct cpu_op *mx6_get_cpu_op(int *op)
*op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op);
return mx6dl_cpu_op;
}
- } else {
+ } else if (cpu_is_mx6q()) {
if (arm_max_freq == CPU_AT_1_2GHz) {
- *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1_2G);
- return mx6_cpu_op_1_2G;
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G);
+ return mx6q_cpu_op_1_2G;
} else if (arm_max_freq == CPU_AT_1GHz) {
- *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1G);
- return mx6_cpu_op_1G;
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G);
+ return mx6q_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op);
+ return mx6q_cpu_op;
+ }
+ } else {
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G);
+ return mx6sl_cpu_op_1G;
} else {
- *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op);
- return mx6_cpu_op;
+ *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op);
+ return mx6sl_cpu_op;
}
}
}
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
index 105e1f6d0a0e..bd948cecbcd2 100644
--- a/arch/arm/mach-mx6/devices-imx6q.h
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -158,10 +158,6 @@ extern const struct imx_imx_asrc_data imx6q_imx_asrc_data[] __initconst;
#define imx6q_add_asrc(pdata) \
imx_add_imx_asrc(imx6q_imx_asrc_data, pdata)
-extern const struct imx_spi_imx_data imx6q_ecspi_data[] __initconst;
-#define imx6q_add_ecspi(id, pdata) \
- imx_add_spi_imx(&imx6q_ecspi_data[id], pdata)
-
extern const struct imx_dvfs_core_data imx6q_dvfs_core_data __initconst;
#define imx6q_add_dvfs_core(pdata) \
imx_add_dvfs_core(&imx6q_dvfs_core_data, pdata)
@@ -220,6 +216,9 @@ extern const struct imx_pxp_data imx6dl_pxp_data __initconst;
#define imx6dl_add_imx_pxp_client() \
imx_add_imx_pxp_client()
+#define imx6sl_add_imx_pxp_v4l2() \
+ imx_add_imx_pxp_v4l2()
+
extern const struct imx_epdc_data imx6dl_epdc_data __initconst;
#define imx6dl_add_imx_epdc(pdata) \
imx_add_imx_epdc(&imx6dl_epdc_data, pdata)
diff --git a/arch/arm/mach-mx6/irq.c b/arch/arm/mach-mx6/irq.c
index 5131eae3a040..0498cd90e8e8 100644
--- a/arch/arm/mach-mx6/irq.c
+++ b/arch/arm/mach-mx6/irq.c
@@ -65,6 +65,14 @@ static struct irq_tuner mxc_irq_tuner[] = {
.up_threshold = 0,
.enable = 0,},
{
+ .irq_number = 42, /* GPU 2D */
+ .up_threshold = 40,
+ .enable = 1,},
+ {
+ .irq_number = 43, /* GPU VG */
+ .up_threshold = 0,
+ .enable = 1,},
+ {
.irq_number = 54, /* uSDHC1 */
.up_threshold = 4,
.enable = 1,},
@@ -103,6 +111,7 @@ void mx6_init_irq(void)
void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
struct irq_desc *desc;
unsigned int i;
+ u32 reg;
/* start offset if private timer irq id, which is 29.
* ID table:
@@ -121,6 +130,13 @@ void mx6_init_irq(void)
__raw_writel(0x20000000, gpc_base + 0x10);
}
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ /* Mask the ANATOP brown out interrupt in the GPC. */
+ reg = __raw_readl(gpc_base + 0x14);
+ reg |= 0x80000000;
+ __raw_writel(reg, gpc_base + 0x14);
+#endif
+
for (i = MXC_INT_START; i <= MXC_INT_END; i++) {
desc = irq_to_desc(i);
desc->irq_data.chip->irq_set_wake = mx6_gic_irq_set_wake;
diff --git a/arch/arm/mach-mx6/mx6_anatop_regulator.c b/arch/arm/mach-mx6/mx6_anatop_regulator.c
index 06755dc7a4ee..945adbdb759a 100644
--- a/arch/arm/mach-mx6/mx6_anatop_regulator.c
+++ b/arch/arm/mach-mx6/mx6_anatop_regulator.c
@@ -125,10 +125,12 @@ static int pu_enable(struct anatop_regulator *sreg)
reg |= ANADIG_ANA_MISC2_REG1_BO_EN;
__raw_writel(reg, ANA_MISC2_BASE_ADDR);
+#ifndef CONFIG_MX6_INTER_LDO_BYPASS
/* Unmask the ANATOP brown out interrupt in the GPC. */
reg = __raw_readl(gpc_base + 0x14);
reg &= ~0x80000000;
__raw_writel(reg, gpc_base + 0x14);
+#endif
return 0;
}
@@ -162,10 +164,12 @@ static int pu_disable(struct anatop_regulator *sreg)
while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x1)
;
+#ifndef CONFIG_MX6_INTER_LDO_BYPASS
/* Mask the ANATOP brown out interrupt in the GPC. */
reg = __raw_readl(gpc_base + 0x14);
reg |= 0x80000000;
__raw_writel(reg, gpc_base + 0x14);
+#endif
/* PU power gating. */
reg = __raw_readl(ANADIG_REG_CORE);
diff --git a/arch/arm/mach-mx6/mx6_suspend.S b/arch/arm/mach-mx6/mx6_suspend.S
index 59b676038427..a9b7e30cd85a 100644
--- a/arch/arm/mach-mx6/mx6_suspend.S
+++ b/arch/arm/mach-mx6/mx6_suspend.S
@@ -85,8 +85,7 @@ r2: suspend_iram_base
ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
ldr r6, [r1, #0x320] /* DRAM_RESET */
- ldr r7, [r1, #0x5c8] /* GPR_CTLDS */
- stmfd r0!, {r4-r7}
+ stmfd r0!, {r4-r6}
.endm
@@ -122,11 +121,10 @@ r2: suspend_iram_base
str r6, [r1, #0x33c] /* DRAM_SODT0*/
str r7, [r1, #0x340] /* DRAM_SODT1*/
- ldmea r0!, {r4-r7}
+ ldmea r0!, {r4-r6}
str r4, [r1, #0x330] /* DRAM_SDCKE0 */
str r5, [r1, #0x334] /* DRAM_SDCKE1 */
str r6, [r1, #0x320] /* DRAM_RESET */
- str r7, [r1, #0x5c8] /* GPR_CTLDS */
.endm
@@ -138,6 +136,13 @@ r2: suspend_iram_base
str r0, [r1, #0x314] /* DRAM_DQM2 */
str r0, [r1, #0x318] /* DRAM_DQM3 */
+ /* Make sure the Pull Ups are enabled.
+ * So only reduce the drive stength, but
+ * leave the pull-ups in the original state.
+ * This is required for LPDDR2.
+ */
+ ldr r0, [r1, #0x344]
+ orr r0, r0, #0x3000
str r0, [r1, #0x344] /* DRAM_SDQS0 */
str r0, [r1, #0x348] /* DRAM_SDQS1 */
str r0, [r1, #0x34c] /* DRAM_SDQS2 */
@@ -158,7 +163,6 @@ r2: suspend_iram_base
str r0, [r1, #0x33c] /* DRAM_SODT0*/
str r0, [r1, #0x340] /* DRAM_SODT1*/
- str r0, [r1, #0x5c8] /* GPR_CTLDS */
mov r0, #0x80000
str r0, [r1, #0x320] /* DRAM_RESET */
mov r0, #0x1000
diff --git a/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c
index cc12a0224ab2..8cb4ffcc78fa 100644
--- a/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c
+++ b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c
@@ -41,13 +41,13 @@
/*SWBST*/
#define PFUZE100_SW1ASTANDBY 33
-#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1BSTANDBY 40
-#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1CSTANDBY 47
-#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW2STANDBY 54
#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
diff --git a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c
index f7e7099468c1..69daddf14000 100644
--- a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c
+++ b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c
@@ -48,13 +48,13 @@
#define PFUZE100_SW1CVOL 46
#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
#define PFUZE100_SW1ASTANDBY 33
-#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1BSTANDBY 40
-#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW1CSTANDBY 47
-#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x18)
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19)
#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
#define PFUZE100_SW2STANDBY 54
#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
@@ -74,6 +74,9 @@
#define PFUZE100_SW1ACON 36
#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
extern u32 arm_max_freq;
@@ -83,6 +86,11 @@ static struct regulator_consumer_supply sw1_consumers[] = {
.supply = "VDDCORE",
}
};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
#endif
static struct regulator_consumer_supply sw2_consumers[] = {
@@ -160,10 +168,10 @@ static struct regulator_init_data sw1a_init = {
.always_on = 1,
},
- #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
.num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
.consumer_supplies = sw1_consumers,
- #endif
+#endif
};
static struct regulator_init_data sw1b_init = {
@@ -188,6 +196,10 @@ static struct regulator_init_data sw1c_init = {
.always_on = 1,
.boot_on = 1,
},
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+#endif
};
static struct regulator_init_data sw2_init = {
@@ -421,12 +433,17 @@ static int pfuze100_init(struct mc_pfuze *pfuze)
PFUZE100_SW1CSTANDBY_STBY_VAL);
if (ret)
goto err;
- /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/
+ /*set SW1AB/1C DVSPEED as 25mV step each 4us,quick than 16us before.*/
ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
PFUZE100_SW1ACON_SPEED_M,
PFUZE100_SW1ACON_SPEED_VAL);
if (ret)
goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
return 0;
err:
printk(KERN_ERR "pfuze100 init error!\n");
diff --git a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
index 0c3f1b20d361..134700a6d200 100644
--- a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
+++ b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
@@ -66,6 +66,9 @@
#define PFUZE100_SW1ACON 36
#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
#ifdef CONFIG_MX6_INTER_LDO_BYPASS
@@ -74,6 +77,11 @@ static struct regulator_consumer_supply sw1_consumers[] = {
.supply = "VDDCORE",
}
};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
#endif
static struct regulator_consumer_supply sw2_consumers[] = {
@@ -151,10 +159,10 @@ static struct regulator_init_data sw1a_init = {
.boot_on = 1,
.always_on = 1,
},
- #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
.num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
.consumer_supplies = sw1_consumers,
- #endif
+#endif
};
static struct regulator_init_data sw1b_init = {
@@ -179,6 +187,10 @@ static struct regulator_init_data sw1c_init = {
.always_on = 1,
.boot_on = 1,
},
+ #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+ #endif
};
static struct regulator_init_data sw2_init = {
@@ -298,8 +310,8 @@ static struct regulator_init_data vgen1_init = {
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS,
.valid_modes_mask = 0,
- .always_on = 0,
- .boot_on = 0,
+ .always_on = 1,
+ .boot_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
.consumer_supplies = vgen1_consumers,
@@ -345,6 +357,8 @@ static struct regulator_init_data vgen4_init = {
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS,
.valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
.consumer_supplies = vgen4_consumers,
@@ -389,12 +403,17 @@ static int pfuze100_init(struct mc_pfuze *pfuze)
PFUZE100_SW1CSTANDBY_STBY_VAL);
if (ret)
goto err;
- /*set SW1ABDVSPEED as 25mV step each 4us,quick than 16us before.*/
+ /*set SW1AB/SW1C DVSPEED as 25mV step each 4us,quick than 16us before.*/
ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
PFUZE100_SW1ACON_SPEED_M,
PFUZE100_SW1ACON_SPEED_VAL);
if (ret)
goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
return 0;
err:
printk(KERN_ERR "pfuze100 init error!\n");
diff --git a/arch/arm/mach-mx6/mx6sl_ddr.S b/arch/arm/mach-mx6/mx6sl_ddr.S
new file mode 100644
index 000000000000..3059f3aa3c8c
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_ddr.S
@@ -0,0 +1,432 @@
+/*
+ * 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 <linux/linkage.h>
+#include <mach/hardware.h>
+
+
+ .macro mx6sl_switch_to_24MHz
+
+ /* Set MMDC clock to be sourced from PLL3. */
+ /* Ensure first periph2_clk2 is sourced from PLL3. */
+ /* Set the PERIPH2_CLK2_PODF to divide by 2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ orr r6, r6, #0x1
+ str r6, [r2, #0x14]
+
+ /* Select PLL3 to source MMDC. */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Swtich periph2_clk_sel to run from PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch1
+
+ /* Need to clock gate the 528 PFDs before
+ * powering down PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC
+ */
+ ldr r6, [r3, #0x100]
+ orr r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+ /* Set PLL2 to bypass state. We should be here
+ *only if MMDC is not sourced from PLL2.*/
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Ensure pre_periph2_clk_mux is set to pll2 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ str r6, [r2, #0x18]
+
+ /* Set MMDC clock to be sourced from the bypassed PLL2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch2:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch2
+
+ /* Now move MMDC back to periph2_clk2 source.
+ * after selecting PLL2 as the option.
+ */
+ /* Select PLL2 as the source. */
+ ldr r6, [r2, #0x18]
+ orr r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* set periph2_clk2_podf to divide by 1. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ str r6, [r2, #0x14]
+
+ /* Now move periph2_clk to periph2_clk2 source */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch3:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch3
+
+ /* Now set the MMDC PODF back to 1.*/
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r2, #0x14]
+
+mmdc_podf0:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf0
+
+ .endm
+
+ .macro ddr_switch_400MHz
+
+ /* Check if we are switching between
+ * 400Mhz <-> 50MHz. If so, we only need to
+ * update MMDC divider.
+ */
+ cmp r1, #0
+ beq change_divider_only
+
+ /* Set MMDC divider first, in case PLL3 is at 480MHz. */
+ ldr r6, [r3, #0x10]
+ and r6, r6, #0x10000
+ cmp r6, #0x10000
+ beq pll3_in_bypass
+ /* Set MMDC divder to divide by 2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x8
+ str r6, [r2, #0x14]
+
+mmdc_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf
+
+pll3_in_bypass:
+
+ /* Ensure that MMDC is sourced from PLL2 mux first. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch4:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch4
+
+ /* Now ensure periph2_clk2_sel mux is set to PLL3 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Now switch MMDC to PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch5:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch5
+
+ /* Now power up PLL2 and unbypass it. */
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Make sure PLL2 has locked.*/
+wait_for_pll_lock:
+ ldr r6, [r3, #0x30]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r3, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+ /* Now switch MMDC clk back to pll2_mux option. */
+ /* Ensure pre_periph2_clk2 is set to pll2_pfd_400M */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ orr r6, r6, #0x200000
+ str r6, [r2, #0x18]
+
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch6:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch6
+
+change_divider_only:
+ /* Calculate the MMDC divider
+ * based on the requested freq.
+ */
+ ldr r6, =400000000
+ ldr r4, =0
+Loop2:
+ sub r6, r6, r0
+ cmp r6, r0
+ blt Div_Found
+ add r4, r4, #1
+ bgt Loop2
+
+ /* Shift divider into correct offset. */
+ lsl r4, r4, #3
+Div_Found:
+ /* Set the MMDC PODF. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, r4
+ str r6, [r2, #0x14]
+
+mmdc_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf1
+
+ .endm
+
+ .macro mmdc_clk_lower_100MHz
+
+ /* Prior to reducing the DDR frequency (at 528/400 MHz),
+ read the Measure unit count bits (MU_UNIT_DEL_NUM) */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r4, =0x3FF
+ and r6, r6, r4
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /* Bypass the automatic measure unit when below 100 MHz
+ by setting the Measure unit bypass enable bit (MU_BYP_EN) */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r8, r5]
+ ldr r4, =0x3FF
+ bic r6, r6, r4
+ orr r6, r6, r7
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure
+
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ bic r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+ .endm
+
+/*
+ * mx6sl_ddr_iram
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : DDR freq.
+ * r1: low_bus_freq_mode flag
+ */
+ENTRY(mx6sl_ddr_iram)
+
+ push {r4, r5, r6, r7, r8, r9, r10 }
+
+mx6sl_ddr_freq_change:
+ ldr r3, =ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+
+ ldr r2, =CCM_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+
+ ldr r8, =MMDC_P0_BASE_ADDR
+ add r8, r8, #PERIPBASE_VIRT
+
+ /* Prime all TLB entries. */
+ adr r7, mx6sl_ddr_freq_change @Address in this function.
+
+ ldr r6, [r7]
+ ldr r6, [r8]
+ ldr r6, [r3]
+ ldr r6, [r2]
+
+ dsb
+ isb
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* Disable MMDC power down timer. */
+ /*MMDC0_MDPDC disable power down timer */
+ ldr r6, [r8, #0x4]
+ bic r6, r6, #0xff00
+ str r6, [r8, #0x4]
+
+ /* Delay for a while */
+ ldr r10, =10
+delay1:
+ ldr r7, =0
+cont1:
+ ldr r6, [r8, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont1
+ sub r10, r10, #1
+ cmp r10, #0
+ bgt delay1
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ ldr r10, =100000000
+ cmp r0, r10
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_100MHz
+
+set_ddr_mu_above_100:
+ ldr r10, =24000000
+ cmp r0, r10
+ beq set_to_24MHz
+
+ ddr_switch_400MHz
+ ldr r10, =100000000
+ cmp r0, r10
+ blt done
+ mmdc_clk_above_100MHz
+ b done
+
+set_to_24MHz:
+ mx6sl_switch_to_24MHz
+
+done:
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ ldr r10, =24000000
+ cmp r0, r10
+ beq skip_power_down
+
+ /* Enable MMDC power down timer. */
+ ldr r6, [r8, #0x4]
+ orr r6, r6, #0x5500
+ str r6, [r8, #0x4]
+
+skip_power_down:
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ pop {r4,r5, r6, r7, r8, r9, r10}
+
+ /* Restore registers */
+ mov pc, lr
+
+ .type mx6sl_ddr_do_iram, #object
+ENTRY(mx6sl_ddr_do_iram)
+ .word mx6sl_ddr_iram
+ .size mx6sl_ddr_iram, . - mx6sl_ddr_iram
diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
new file mode 100644
index 000000000000..ee66541f8bff
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <mach/irqs.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+ /*SWBST*/
+#define PFUZE100_SW1ASTANDBY 33
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW1BSTANDBY 40
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW1CSTANDBY 47
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x16)
+#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW2STANDBY 54
+#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
+#define PFUZE100_SW2STANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW3ASTANDBY 61
+#define PFUZE100_SW3ASTANDBY_STBY_VAL 0x0
+#define PFUZE100_SW3ASTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW3BSTANDBY 68
+#define PFUZE100_SW3BSTANDBY_STBY_VAL 0x0
+#define PFUZE100_SW3BSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW4STANDBY 75
+#define PFUZE100_SW4STANDBY_STBY_VAL 0
+#define PFUZE100_SW4STANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SWBSTCON1 102
+#define PFUZE100_SWBSTCON1_SWBSTMOD_VAL (0x1<<2)
+#define PFUZE100_SWBSTCON1_SWBSTMOD_M (0x3<<2)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
+#endif
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "MICVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "AUD_1V8",
+ }
+};
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "SWBST_5V",
+ }
+};
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "VGEN1_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "VGEN2_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen3_consumers[] = {
+ {
+ .supply = "AVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DCVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "CPVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "PLLVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DBVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "VGEN4_1V8",
+ }
+};
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "VGEN5_2V8",
+ }
+};
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "VGEN6_3V3",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+#endif
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+#endif
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "PFUZE100_SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "PFUZE100_SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "PFUZE100_SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "PFUZE100_VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "PFUZE100_VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen3_consumers),
+ .consumer_supplies = vgen3_consumers,
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ASTANDBY,
+ PFUZE100_SW1ASTANDBY_STBY_M,
+ PFUZE100_SW1ASTANDBY_STBY_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CSTANDBY,
+ PFUZE100_SW1CSTANDBY_STBY_M,
+ PFUZE100_SW1CSTANDBY_STBY_VAL);
+ if (ret)
+ goto err;
+ /*set SW1AB/SW1CDVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+ {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6sl_evk_init_pfuze100(u32 int_gpio)
+{
+ if (int_gpio)
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(0, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S
new file mode 100644
index 000000000000..89fe4e292352
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_wfi.S
@@ -0,0 +1,412 @@
+/*
+ * 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 <linux/linkage.h>
+#include <mach/hardware.h>
+#define IRAM_WAIT_SIZE (1 << 11)
+
+
+ .macro sl_ddr_io_save
+
+ ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
+ ldr r5, [r1, #0x310] /* DRAM_DQM1 */
+ ldr r6, [r1, #0x314] /* DRAM_DQM2 */
+ ldr r7, [r1, #0x318] /* DRAM_DQM3 */
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x344] /* DRAM_SDQS0 */
+ ldr r5, [r1, #0x348] /* DRAM_SDQS1 */
+ ldr r6, [r1, #0x34c] /* DRAM_SDQS2 */
+ ldr r7, [r1, #0x350] /* DRAM_SDQS3 */
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x5c4] /* GPR_B0DS */
+ ldr r5, [r1, #0x5cc] /* GPR_B1DS */
+ ldr r6, [r1, #0x5d4] /* GPR_B2DS */
+ ldr r7, [r1, #0x5d8] /* GPR_B3DS */
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x300] /* DRAM_CAS */
+ ldr r5, [r1, #0x31c] /* DRAM_RAS */
+ ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ ldr r5, [r1, #0x5c0] /* DDRMODE */
+ ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
+ ldr r7, [r1, #0x340] /* DRAM_SODT1*/
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ ldr r6, [r1, #0x320] /* DRAM_RESET */
+ ldr r7, [r1, #0x5c8] /* GPR_CTLDS */
+ stmfd r9!, {r4-r7}
+
+ .endm
+
+ .macro sl_ddr_io_restore
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x30c] /* DRAM_DQM0 */
+ str r5, [r1, #0x310] /* DRAM_DQM1 */
+ str r6, [r1, #0x314] /* DRAM_DQM2 */
+ str r7, [r1, #0x318] /* DRAM_DQM3 */
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x344] /* DRAM_SDQS0 */
+ str r5, [r1, #0x348] /* DRAM_SDQS1 */
+ str r6, [r1, #0x34c] /* DRAM_SDQS2 */
+ str r7, [r1, #0x350] /* DRAM_SDQS3 */
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x5c4] /* GPR_B0DS */
+ str r5, [r1, #0x5cc] /* GPR_B1DS */
+ str r6, [r1, #0x5d4] /* GPR_B2DS */
+ str r7, [r1, #0x5d8] /* GPR_B3DS */
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x300] /* DRAM_CAS */
+ str r5, [r1, #0x31c] /* DRAM_RAS */
+ str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r7, [r1, #0x5ac] /* GPR_ADDS*/
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r5, [r1, #0x5c0] /* DDRMODE */
+ str r6, [r1, #0x33c] /* DRAM_SODT0*/
+ str r7, [r1, #0x340] /* DRAM_SODT1*/
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ str r6, [r1, #0x320] /* DRAM_RESET */
+ str r7, [r1, #0x5c8] /* GPR_CTLDS */
+
+ .endm
+
+ .macro sl_ddr_io_set_lpm
+
+ mov r4, #0
+ str r4, [r1, #0x30c] /* DRAM_DQM0 */
+ str r4, [r1, #0x310] /* DRAM_DQM1 */
+ str r4, [r1, #0x314] /* DRAM_DQM2 */
+ str r4, [r1, #0x318] /* DRAM_DQM3 */
+
+ /* Make sure the Pull Ups are enabled.
+ * So only reduce the drive stength, but
+ * leave the pull-ups in the original state.
+ * This is required for LPDDR2.
+ */
+ ldr r4, [r1, #0x344]
+ orr r4, r4, #0x3000
+ str r4, [r1, #0x344] /* DRAM_SDQS0 */
+ str r4, [r1, #0x348] /* DRAM_SDQS1 */
+ str r4, [r1, #0x34c] /* DRAM_SDQS2 */
+ str r4, [r1, #0x350] /* DRAM_SDQS3 */
+
+ str r4, [r1, #0x5c4] /* GPR_B0DS */
+ str r4, [r1, #0x5cc] /* GPR_B1DS */
+ str r4, [r1, #0x5d4] /* GPR_B2DS */
+ str r4, [r1, #0x5d8] /* GPR_B3DS */
+
+ str r4, [r1, #0x300] /* DRAM_CAS */
+ str r4, [r1, #0x31c] /* DRAM_RAS */
+ str r4, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r4, [r1, #0x5ac] /* GPR_ADDS*/
+
+ str r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r4, [r1, #0x5c0] /* DDRMODE */
+ str r4, [r1, #0x33c] /* DRAM_SODT0*/
+ str r4, [r1, #0x340] /* DRAM_SODT1*/
+
+ mov r4, #0x80000
+ str r4, [r1, #0x320] /* DRAM_RESET */
+ mov r4, #0x1000
+ str r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r4, [r1, #0x334] /* DRAM_SDCKE1 */
+
+ .endm
+
+/*
+ * mx6sl_wait
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : arm_podf before WFI is entered
+ * r1: WFI IRAMcode base address.
+ */
+ENTRY(mx6sl_wait)
+
+ push {r4, r5, r6, r7, r8, r9, r10}
+
+mx6sl_lpm_wfi:
+ /* Get the IRAM data storage address. */
+ mov r10, r1
+ mov r9, r1 /* get suspend_iram_base */
+ add r9, r9, #IRAM_WAIT_SIZE /* 4K */
+
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Save the DDR IO state. */
+ sl_ddr_io_save
+
+ ldr r3, =ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+
+ ldr r2, =CCM_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+
+ ldr r8, =MMDC_P0_BASE_ADDR
+ add r8, r8, #PERIPBASE_VIRT
+
+
+ /* Prime all TLB entries. */
+ adr r7, mx6sl_lpm_wfi @Address in this function.
+
+ ldr r6, [r7]
+
+ ldr r6, [r8]
+ ldr r6, [r3]
+ ldr r6, [r2]
+ ldr r6, [r1]
+
+ dsb
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ /* Now set DDR rate to 1MHz. */
+ /* DDR is from bypassed PLL2 on periph2_clk2 path.
+ * Set the periph2_clk2_podf to divide by 8.
+ */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x07
+ str r6, [r2, #0x14]
+
+ /* Now set MMDC PODF to divide by 3. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x10
+ str r6, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+mmdc_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne mmdc_podf
+
+ /* Set the DDR IO in LPM state. */
+ sl_ddr_io_set_lpm
+
+ /* Set AHB to 8MHz., AXI to 3MHz */
+ /* We want to ensure IPG_PERCLK to AHB
+ * clk ratio is 1:2.5
+ */
+ /* Store the AXI/AHB podfs. */
+ ldr r9, [r2, #0x14]
+ mov r6, r9
+ bic r6, r6, #0x1c00
+ orr r6, r6, #0x800
+ orr r6, r6, #0x70000
+ str r6, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+ahb_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop
+
+ /* Now set ARM to 24MHz. */
+ /* Move ARM to be sourced from STEP_CLK
+ * after setting STEP_CLK to 24MHz.
+ */
+ ldr r6, [r2, #0xc]
+ bic r6, r6, #0x100
+ str r6, [r2, #0x0c]
+ /* Now PLL1_SW_CLK to step_clk. */
+ ldr r6, [r2, #0x0c]
+ orr r6, r6, #0x4
+ str r6, [r2, #0x0c]
+
+ /* Bypass PLL1 and power it down. */
+ ldr r6, =(1 << 16)
+ orr r6, r6, #0x1000
+ str r6, [r3, #0x04]
+
+ /* Set the ARM PODF to divide by 8. */
+ /* IPG is at 4MHz here, we need ARM to
+ * run at the 12:5 ratio (WAIT mode issue).
+ */
+ ldr r6, =0x7
+ str r6, [r2, #0x10]
+
+ /* Loop till podf is accepted. */
+podf_loop:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop
+
+ /* Now do WFI. */
+ dsb
+
+ wfi
+
+ /* Set original ARM PODF back. */
+ str r0, [r2, #0x10]
+
+ /* Loop till podf is accepted. */
+podf_loop1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop1
+
+ /* Power up PLL1 and un-bypass it. */
+ ldr r6, =(1 << 12)
+ str r6, [r3, #0x08]
+
+ /* Wait for PLL1 to relock. */
+wait_for_pll_lock:
+ ldr r6, [r3, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ ldr r6, =(1 << 16)
+ str r6, [r3, #0x08]
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r2, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r2, #0xc]
+
+ /* Restore AHB/AXI back. */
+ str r9, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+ahb_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop1
+
+ mov r9, r10 /* get suspend_iram_base */
+ add r9, r9, #IRAM_WAIT_SIZE /* 4K */
+
+ /* Restore the DDR IO before exiting self-refresh. */
+ sl_ddr_io_restore
+
+ /* Set MMDC back to 24MHz. */
+ /* Set periph2_clk2_podf to divide by 1. */
+ /* Now set MMDC PODF to divide by 1. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x3f
+ str r6, [r2, #0x14]
+
+mmdc_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne mmdc_podf1
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Add these nops so that the
+ * prefetcher will not try to get
+ * any instructions from DDR.
+ * The prefetch depth is about 23
+ * on A9, so adding 25 nops.
+ */
+ 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
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+
+ pop {r4,r5, r6, r7, r8, r9, r10}
+
+ /* Restore registers */
+ mov pc, lr
+
+ .type mx6sl_do_wait, #object
+ENTRY(mx6sl_do_wait)
+ .word mx6sl_wait
+ .size mx6sl_wait, . - mx6sl_wait
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c
index b1d91e311b5e..c19d895139cf 100644
--- a/arch/arm/mach-mx6/pm.c
+++ b/arch/arm/mach-mx6/pm.c
@@ -38,6 +38,7 @@
#endif
#include "crm_regs.h"
#include "src-reg.h"
+#include "regs-anadig.h"
#define SCU_CTRL_OFFSET 0x00
#define GPC_IMR1_OFFSET 0x08
@@ -118,6 +119,11 @@ static void usb_power_down_handler(void)
{
u32 temp;
bool usb_oh3_clk_already_on;
+ if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0)
+ & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) != 0) {
+ usb_vbus_wakeup_enabled = false;
+ return;
+ }
/* enable usb oh3 clock if needed*/
temp = __raw_readl(MXC_CCM_CCGR6);
usb_oh3_clk_already_on = \
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index 57dee5f4c4c0..800c7cc4e8bd 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -52,14 +52,14 @@ extern unsigned int gpc_wake_irq[4];
static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
-int wait_mode_arm_podf;
volatile unsigned int num_cpu_idle;
volatile unsigned int num_cpu_idle_lock = 0x0;
int wait_mode_arm_podf;
int cur_arm_podf;
-bool arm_mem_clked_in_wait;
void arch_idle_with_workaround(int cpu);
+extern void *mx6sl_wfi_iram_base;
+extern void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr);
extern void mx6_wait(void *num_cpu_idle_lock, void *num_cpu_idle, \
int wait_arm_podf, int cur_arm_podf);
extern bool enable_wait_mode;
@@ -78,6 +78,7 @@ void gpc_set_wakeup(unsigned int irq[4])
return;
}
+
/* set cpu low power mode before WFI instruction */
void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
{
@@ -194,7 +195,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
__raw_writel(__raw_readl(MXC_CCM_CCR) &
(~MXC_CCM_CCR_WB_COUNT_MASK) &
(~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR);
- udelay(60);
+ udelay(80);
/* Reconfigurate WB and RBC counter */
__raw_writel(__raw_readl(MXC_CCM_CCR) |
(0x1 << MXC_CCM_CCR_WB_COUNT_OFFSET) |
@@ -251,25 +252,54 @@ void arch_idle_single_core(void)
ca9_do_idle();
} else {
- /*
- * Implement the 12:5 ARM:IPG_CLK ratio
- * workaround for the WAIT mode issue.
- * We can directly use the divider to drop the ARM
- * core freq in a single core environment.
- * Set the ARM_PODF to get the max freq possible
- * to avoid the WAIT mode issue when IPG is at 66MHz.
- */
- if (cpu_is_mx6sl()) {
- reg = __raw_readl(MXC_CCM_CGPR);
- reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
- __raw_writel(reg, MXC_CCM_CGPR);
- }
- __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR);
- while (__raw_readl(MXC_CCM_CDHIPR))
- ;
- ca9_do_idle();
+ if (low_bus_freq_mode || audio_bus_freq_mode) {
+ if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ /* In this mode PLL2 i already in bypass,
+ * ARM is sourced from PLL1. The code in IRAM
+ * will set ARM to be sourced from STEP_CLK
+ * at 24MHz. It will also set DDR to 1MHz to
+ * reduce power.
+ */
+ u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR);
- __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
+ /* Need to run WFI code from IRAM so that
+ * we can lower DDR freq.
+ */
+ mx6sl_wfi_iram(org_arm_podf,
+ (unsigned long)mx6sl_wfi_iram_base);
+ } else {
+ /* Need to set ARM to run at 24MHz since IPG
+ * is at 12MHz. This is valid for audio mode on
+ * MX6SL, and all low power modes on MX6DLS.
+ */
+ /* PLL1_SW_CLK is sourced from PLL2_PFD2400MHz
+ * at this point. Move it to bypassed PLL1.
+ */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ ca9_do_idle();
+
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
+ } else {
+ /*
+ * Implement the 12:5 ARM:IPG_CLK ratio
+ * workaround for the WAIT mode issue.
+ * We can directly use the divider to drop the ARM
+ * core freq in a single core environment.
+ * Set the ARM_PODF to get the max freq possible
+ * to avoid the WAIT mode issue when IPG is at 66MHz.
+ */
+ __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ ca9_do_idle();
+
+ __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
+ }
}
}
@@ -331,7 +361,7 @@ void arch_idle(void)
{
if (enable_wait_mode) {
mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
- if ((mem_clk_on_in_wait || arm_mem_clked_in_wait)) {
+ if (mem_clk_on_in_wait) {
u32 reg;
/*
* MX6SL, MX6Q (TO1.2 or later) and
diff --git a/arch/arm/mach-mx6/usb.h b/arch/arm/mach-mx6/usb.h
index f796e7dad87c..6914246826f6 100644
--- a/arch/arm/mach-mx6/usb.h
+++ b/arch/arm/mach-mx6/usb.h
@@ -30,6 +30,9 @@ extern void gpio_usbotg_utmi_inactive(void);
extern void __init mx6_usb_dr_init(void);
extern bool usb_icbug_swfix_need(void);
+extern int usb_stop_mode_refcount(bool enable);
+extern void usb_stop_mode_lock(void);
+extern void usb_stop_mode_unlock(void);
extern void __init mx6_usb_h2_init(void);
extern void __init mx6_usb_h3_init(void);
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index 1efac33aa7fc..8fe9700a658f 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -173,6 +173,9 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
static int usbotg_init_ext(struct platform_device *pdev)
{
struct clk *usb_clk;
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+#endif
u32 ret;
/* at mx6q: this clock is AHB clock for usb core */
@@ -198,6 +201,12 @@ static int usbotg_init_ext(struct platform_device *pdev)
mdelay(3);
}
otg_used++;
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ usb_stop_mode_lock();
+ if (usb_stop_mode_refcount(true) == 1)
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+ usb_stop_mode_unlock();
+#endif
return ret;
}
@@ -205,6 +214,9 @@ static int usbotg_init_ext(struct platform_device *pdev)
static void usbotg_uninit_ext(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+#endif
clk_disable(usb_phy1_clk);
clk_put(usb_phy1_clk);
@@ -214,6 +226,12 @@ static void usbotg_uninit_ext(struct platform_device *pdev)
usbotg_uninit(pdata);
otg_used--;
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ usb_stop_mode_lock();
+ if (usb_stop_mode_refcount(false) == 0)
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR);
+ usb_stop_mode_unlock();
+#endif
}
static void usbotg_clock_gate(bool on)
@@ -424,18 +442,18 @@ static void _host_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
{
u32 index = 0;
- if ((UOG_PORTSC1 & (3 << 26)) != (2 << 26))
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
return ;
-
while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
&& (index < 1000)) {
udelay(500);
index++;
}
-
if (index >= 1000)
- printk(KERN_INFO "%s big error\n", __func__);
-
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
udelay(500);
fsl_platform_otg_set_usb_phy_dis(pdata, 1);
}
@@ -451,9 +469,24 @@ static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
{
+ u32 index = 0;
+
/*for mx6sl ,we do not need any sw fix*/
if (cpu_is_mx6sl())
return ;
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
MX6_IO_ADDRESS(pdata->phy_regs)
+ HW_USBPHY_CTRL_SET);
diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c
index 92ef0ec3c3f5..bece29f7d44b 100644
--- a/arch/arm/mach-mx6/usb_h1.c
+++ b/arch/arm/mach-mx6/usb_h1.c
@@ -134,6 +134,7 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev)
{
int ret;
struct clk *usb_clk;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
usb_clk = clk_get(NULL, "usboh3_clk");
clk_enable(usb_clk);
usb_oh3_clk = usb_clk;
@@ -145,19 +146,25 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev)
}
usbh1_internal_phy_clock_gate(true);
usb_phy_enable(pdev->dev.platform_data);
-
+ usb_stop_mode_lock();
+ if (usb_stop_mode_refcount(true) == 1)
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+ usb_stop_mode_unlock();
return 0;
}
static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
fsl_usb_host_uninit(pdata);
clk_disable(usb_oh3_clk);
clk_put(usb_oh3_clk);
-
+ usb_stop_mode_lock();
+ if (usb_stop_mode_refcount(false) == 0)
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR);
+ usb_stop_mode_unlock();
}
static void usbh1_clock_gate(bool on)
@@ -237,18 +244,18 @@ static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
{
u32 index = 0;
- if ((UH1_PORTSC1 & (3 << 26)) != (2 << 26))
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
return ;
-
while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
&& (index < 1000)) {
udelay(500);
index++;
}
-
if (index >= 1000)
- printk(KERN_INFO "%s big error\n", __func__);
-
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
udelay(500);
fsl_platform_h1_set_usb_phy_dis(pdata, 1);
}
@@ -265,9 +272,24 @@ static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
{
+ u32 index = 0;
+
/*for mx6sl ,we do not need any sw fix*/
if (cpu_is_mx6sl())
return ;
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
MX6_IO_ADDRESS(pdata->phy_regs)
+ HW_USBPHY_CTRL_SET);
diff --git a/arch/arm/mach-mx6/usb_h2.c b/arch/arm/mach-mx6/usb_h2.c
index 24083fd52d72..37cad034d173 100644
--- a/arch/arm/mach-mx6/usb_h2.c
+++ b/arch/arm/mach-mx6/usb_h2.c
@@ -227,9 +227,16 @@ void __init mx6_usb_h2_init(void)
struct platform_device *pdev, *pdev_wakeup;
static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
usbh2_config.wakeup_pdata = &usbh2_wakeup_config;
- pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config);
+ if (cpu_is_mx6sl())
+ pdev = imx6sl_add_fsl_ehci_hs(2, &usbh2_config);
+ else
+ pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config);
+
usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
- pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
+ if (cpu_is_mx6sl())
+ pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
+ else
+ pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
pdev_wakeup->dev.platform_data;
/* Some phy and power's special controls for host2