summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-08-01 10:03:09 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-08-01 10:03:09 +0800
commitd81dac54ea06a1f8a74acf91499d5946d94d9e6a (patch)
treea137a6698343f3dfb880456cc4d89872f2a9b877 /arch
parentc72eec4afb9215391f06c1a1ce14a63e17ed64e2 (diff)
parent091604c85f017199cae9d437545a96157ab063e0 (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.35' into imx_3.0.35_android
Conflicts: drivers/mxc/vpu/mxc_vpu.c
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/configs/imx6_defconfig1
-rw-r--r--arch/arm/configs/imx6s_defconfig1
-rw-r--r--arch/arm/mach-mx6/Kconfig4
-rw-r--r--arch/arm/mach-mx6/Makefile3
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c11
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c16
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c9
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c3
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_arm2.c9
-rw-r--r--arch/arm/mach-mx6/bus_freq.c12
-rw-r--r--arch/arm/mach-mx6/clock.c21
-rwxr-xr-xarch/arm/mach-mx6/clock_mx6sl.c13
-rw-r--r--arch/arm/mach-mx6/cpu.c8
-rw-r--r--arch/arm/mach-mx6/crm_regs.h1
-rw-r--r--arch/arm/mach-mx6/mx6_wfi.S22
-rw-r--r--arch/arm/mach-mx6/system.c154
-rw-r--r--arch/arm/mach-mx6/usb.h17
-rw-r--r--arch/arm/mach-mx6/usb_dr.c34
-rw-r--r--arch/arm/mach-mx6/usb_h1.c107
-rwxr-xr-xarch/arm/plat-mxc/cpufreq.c6
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c1
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-ehci.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/sdma.h1
-rwxr-xr-xarch/arm/plat-mxc/usb_common.c24
-rwxr-xr-xarch/arm/plat-mxc/usb_wakeup.c11
26 files changed, 350 insertions, 143 deletions
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
index e032e6cc3de3..181cf312d2b4 100644
--- a/arch/arm/configs/imx6_defconfig
+++ b/arch/arm/configs/imx6_defconfig
@@ -1938,6 +1938,7 @@ CONFIG_USB_OTG=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ARC=y
CONFIG_USB_EHCI_ARC_OTG=y
+CONFIG_USB_EHCI_ARC_H1=y
# CONFIG_USB_EHCI_ARC_HSIC is not set
# CONFIG_USB_STATIC_IRAM is not set
CONFIG_USB_EHCI_ROOT_HUB_TT=y
diff --git a/arch/arm/configs/imx6s_defconfig b/arch/arm/configs/imx6s_defconfig
index 78efc6b7563e..04c445e3258b 100644
--- a/arch/arm/configs/imx6s_defconfig
+++ b/arch/arm/configs/imx6s_defconfig
@@ -1924,6 +1924,7 @@ CONFIG_USB_OTG=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ARC=y
CONFIG_USB_EHCI_ARC_OTG=y
+CONFIG_USB_EHCI_ARC_H1=y
# CONFIG_USB_EHCI_ARC_HSIC is not set
# CONFIG_USB_STATIC_IRAM is not set
CONFIG_USB_EHCI_ROOT_HUB_TT=y
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 5c60c560f03a..08875a60a31c 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -218,6 +218,10 @@ config IMX_PCIE
bool "PCI Express support"
select PCI
+config USB_EHCI_ARC_H1
+ tristate "USB Host 1 support"
+ depends on USB_EHCI_ARC
+
config MX6_INTER_LDO_BYPASS
bool "Internal LDO in MX6Q/DL bypass"
depends on REGULATOR_PFUZE100 && CPU_FREQ_IMX && ARCH_MX6
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index 03ae8ddfc75d..24dae23dd089 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -3,7 +3,7 @@
#
# 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_h1.o usb_h2.o usb_h3.o \
+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
@@ -16,3 +16,4 @@ obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_
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
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index c335e5e451c0..f298e8d67c06 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -182,9 +182,9 @@ 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;
- iomux_v3_cfg_t *sd_pads_100mhz;
- iomux_v3_cfg_t *sd_pads_50mhz;
+ 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;
@@ -390,7 +390,7 @@ static struct mtd_partition m25p32_partitions[] = {
{
.name = "bootloader",
.offset = 0,
- .size = 0x00040000,
+ .size = 0x00100000,
}, {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
@@ -1240,7 +1240,6 @@ static void __init mx6_arm2_init_usb(void)
mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
mx6_usb_dr_init();
- mx6_usb_h1_init();
#ifdef CONFIG_USB_EHCI_ARC_HSIC
mx6_usb_h2_init();
mx6_usb_h3_init();
@@ -1410,6 +1409,8 @@ static void hdmi_init(int ipu_id, int disp_id)
/* GPR3, bits 2-3 = HDMI_MUX_CTL */
mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+ /* GPR0, bit 0 = 1 */
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
}
/* On mx6x arm2 board i2c2 iomux with hdmi ddc,
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
index 7d2eab2c89f2..2acfea71f331 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -55,6 +55,7 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
+#include <linux/mxc_asrc.h>
#include <sound/pcm.h>
#include <mach/common.h>
@@ -224,9 +225,9 @@ 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;
- iomux_v3_cfg_t *sd_pads_100mhz;
- iomux_v3_cfg_t *sd_pads_50mhz;
+ 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;
@@ -401,7 +402,7 @@ static struct mtd_partition m25p32_partitions[] = {
{
.name = "bootloader",
.offset = 0,
- .size = 0x00040000,
+ .size = 0x00100000,
}, {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
@@ -757,7 +758,6 @@ static void __init imx6q_sabreauto_init_usb(void)
mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus);
mx6_usb_dr_init();
mx6_set_host1_vbus_func(imx6q_sabreauto_usbhost1_vbus);
- mx6_usb_h1_init();
#ifdef CONFIG_USB_EHCI_ARC_HSIC
mx6_usb_h2_init();
mx6_usb_h3_init();
@@ -1075,9 +1075,15 @@ static const struct pm_platform_data mx6q_sabreauto_pm_data __initconst = {
.suspend_exit = sabreauto_suspend_exit,
};
+static const struct asrc_p2p_params esai_p2p = {
+ .p2p_rate = 48000,
+ .p2p_width = ASRC_WIDTH_24_BIT,
+};
+
static struct mxc_audio_platform_data sab_audio_data = {
.sysclk = 24576000,
.codec_name = "cs42888.1-0048",
+ .priv = (void *)&esai_p2p,
};
static struct platform_device sab_audio_device = {
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index 925dfb71ea0e..16ee57e1df2b 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -365,9 +365,9 @@ 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;
- iomux_v3_cfg_t *sd_pads_100mhz;
- iomux_v3_cfg_t *sd_pads_50mhz;
+ 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;
@@ -482,7 +482,7 @@ static struct mtd_partition imx6_sabrelite_spi_nor_partitions[] = {
{
.name = "bootloader",
.offset = 0,
- .size = 0x00040000,
+ .size = 0x00100000,
},
{
.name = "kernel",
@@ -660,7 +660,6 @@ static void __init imx6q_sabrelite_init_usb(void)
mx6_set_otghost_vbus_func(imx6q_sabrelite_usbotg_vbus);
mx6_usb_dr_init();
- mx6_usb_h1_init();
}
/* HW Initialization, if return 0, initialization is successful. */
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index bdcef07c6a4e..ee40c551bbb8 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -298,7 +298,7 @@ static struct mtd_partition imx6_sabresd_spi_nor_partitions[] = {
{
.name = "bootloader",
.offset = 0,
- .size = 0x00040000,
+ .size = 0x00100000,
},
{
.name = "kernel",
@@ -1118,7 +1118,6 @@ static void __init imx6q_sabresd_init_usb(void)
mx6_set_otghost_vbus_func(imx6q_sabresd_usbotg_vbus);
mx6_usb_dr_init();
- mx6_usb_h1_init();
}
/* HW Initialization, if return 0, initialization is successful. */
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c
index 2efca1ba5d93..0097fdc05fa7 100755
--- a/arch/arm/mach-mx6/board-mx6sl_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c
@@ -146,9 +146,9 @@ 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;
- iomux_v3_cfg_t *sd_pads_100mhz;
- iomux_v3_cfg_t *sd_pads_50mhz;
+ 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;
@@ -458,7 +458,7 @@ static struct mtd_partition m25p32_partitions[] = {
{
.name = "bootloader",
.offset = 0,
- .size = 0x00040000,
+ .size = 0x00100000,
}, {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
@@ -1127,7 +1127,6 @@ static void __init mx6_arm2_init_usb(void)
mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
mx6_usb_dr_init();
- mx6_usb_h1_init();
#ifdef CONFIG_USB_EHCI_ARC_HSIC
mx6_usb_h2_init();
#endif
diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c
index b1a0af0f3d35..12dea1474d9a 100644
--- a/arch/arm/mach-mx6/bus_freq.c
+++ b/arch/arm/mach-mx6/bus_freq.c
@@ -78,6 +78,8 @@ void set_ddr_freq(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;
struct mutex bus_freq_mutex;
@@ -128,7 +130,6 @@ static void reduce_bus_freq_handler(struct work_struct *work)
if (!cpu_is_mx6sl()) {
clk_enable(pll3);
-
if (lp_audio_freq) {
/* Need to ensure that PLL2_PFD_400M is kept ON. */
clk_enable(pll2_400);
@@ -149,6 +150,7 @@ static void reduce_bus_freq_handler(struct work_struct *work)
if (med_bus_freq_mode)
clk_disable(pll2_400);
+
clk_disable(pll3);
} else {
/* Set VDDSOC_CAP to 1.1V */
@@ -162,6 +164,8 @@ static void reduce_bus_freq_handler(struct work_struct *work)
udelay(150);
+ arm_mem_clked_in_wait = true;
+
/* Set periph_clk to be sourced from OSC_CLK */
/* Set MMDC clk to 25MHz. */
/* First need to set the divider before changing the parent */
@@ -305,6 +309,12 @@ int set_high_bus_freq(int high_bus_freq)
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;
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 600cd8b23414..34c26d4d3bc0 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -50,8 +50,6 @@ extern int lp_med_freq;
extern int wait_mode_arm_podf;
extern int lp_audio_freq;
extern int cur_arm_podf;
-extern bool arm_mem_clked_in_wait;
-extern bool enable_wait_mode;
void __iomem *apll_base;
@@ -1295,23 +1293,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
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;
- if (wait_mode_arm_podf > 7) {
- /* IPG_CLK is too low and we cannot get a ARM_CLK
- * that will satisfy the 12:5 ratio.
- * Use the mem_ipg_stop_mask bit to ensure clocks to ARM
- * memories are not gated during WAIT mode.
- * This bit is NOT available on MX6DQ TO1.1/TO1.0 and
- * MX6DL TO1.0.
- * Else disable entry to WAIT mode.
- */
- if ((mx6q_revision() > IMX_CHIP_REVISION_1_1) ||
- (mx6dl_revision() > IMX_CHIP_REVISION_1_0))
- arm_mem_clked_in_wait = true;
- else {
- enable_wait_mode = false;
- pr_info("wait mode is disabled due to ipg clock is too low\n");
- }
- }
if (div == 0)
div = 1;
@@ -5383,7 +5364,7 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
/* on mx6dl gpu2d_axi_clk source from mmdc0 directly */
clk_set_parent(&gpu2d_axi_clk, &mmdc_ch0_axi_clk[0]);
- clk_set_parent(&ipu1_clk, &pll2_pfd_400M);
+ clk_set_parent(&ipu1_clk, &pll3_pfd_540M);
/* pxp & epdc */
clk_set_parent(&ipu2_clk, &pll2_pfd_400M);
clk_set_rate(&ipu2_clk, 200000000);
diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c
index 577a52277d68..887e6ad6fa96 100755
--- a/arch/arm/mach-mx6/clock_mx6sl.c
+++ b/arch/arm/mach-mx6/clock_mx6sl.c
@@ -52,7 +52,6 @@ extern int lp_high_freq;
extern int lp_med_freq;
extern int wait_mode_arm_podf;
extern int mx6q_revision(void);
-extern bool arm_mem_clked_in_wait;
extern int cur_arm_podf;
static void __iomem *apll_base;
@@ -1180,16 +1179,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
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;
- if (wait_mode_arm_podf > 7)
- /* IPG_CLK is too low and we cannot get a ARM_CLK
- * that will satisfy the 12:5 ratio.
- * Use the mem_ipg_stop_mask bit to ensure clocks
- * to ARM memories are not gated during WAIT mode.
- * Else disable entry to WAIT mode.
- */
- arm_mem_clked_in_wait = true;
- else
- arm_mem_clked_in_wait = false;
if (div == 0)
div = 1;
@@ -3964,7 +3953,7 @@ int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
/* keep correct count. */
clk_enable(&cpu_clk);
clk_enable(&periph_clk);
- clk_enable(&mmdc_ch1_axi_clk);
+ clk_enable(&mmdc_ch1_axi_clk[0]);
clk_tree_init();
diff --git a/arch/arm/mach-mx6/cpu.c b/arch/arm/mach-mx6/cpu.c
index 5d9749653988..9a60d9817ec3 100644
--- a/arch/arm/mach-mx6/cpu.c
+++ b/arch/arm/mach-mx6/cpu.c
@@ -35,6 +35,7 @@ struct cpu_op *(*get_cpu_op)(int *op);
bool enable_wait_mode = true;
u32 arm_max_freq = CPU_AT_1GHz;
bool mem_clk_on_in_wait;
+int chip_rev;
void __iomem *gpc_base;
void __iomem *ccm_base;
@@ -197,6 +198,13 @@ static int __init post_cpu_init(void)
(mx6dl_revision() < IMX_CHIP_REVISION_1_1))
mem_clk_on_in_wait = false;
+ if (cpu_is_mx6q())
+ chip_rev = mx6q_revision();
+ else if (cpu_is_mx6dl())
+ chip_rev = mx6dl_revision;
+ else
+ chip_rev = mx6sl_revision;
+
return 0;
}
postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx6/crm_regs.h b/arch/arm/mach-mx6/crm_regs.h
index 2e1f3e4a32c4..5e03312b7fce 100644
--- a/arch/arm/mach-mx6/crm_regs.h
+++ b/arch/arm/mach-mx6/crm_regs.h
@@ -498,6 +498,7 @@
#define MXC_CCM_CGPR_MMDC_EXT_CLK_DIS (1 << 2)
#define MXC_CCM_CGPR_PMIC_DELAY_SCALER (1)
#define MXC_CCM_CGPR_MEM_IPG_STOP_MASK (1 << 1)
+#define MXC_CCM_CGPR_WAIT_MODE_FIX (1 << 17)
/* Define the bits in registers CCGRx */
#define MXC_CCM_CCGRx_CG_MASK 0x3
diff --git a/arch/arm/mach-mx6/mx6_wfi.S b/arch/arm/mach-mx6/mx6_wfi.S
index a616dabc4a80..afe7b9a3f6cd 100644
--- a/arch/arm/mach-mx6/mx6_wfi.S
+++ b/arch/arm/mach-mx6/mx6_wfi.S
@@ -28,7 +28,7 @@
*/
ENTRY(mx6_wait)
- push {r4, r5, r6, r7, r8}
+ push {r4, r5, r6, r7, r8, r9}
mov r7, r2 /* Store the arm_podf to be used. */
mov r6, r3
@@ -69,8 +69,11 @@ ENTRY(mx6_wait)
/* Check to see if we need to switch to 24MHz */
cmp r7, #0
bne use_podf
- ldr r6, =(1 << 16)
- str r6, [r2, #0x04]
+ /* Switch ARM to PLL1 output. */
+ /* PLL1 should already be in bypass state. */
+ ldr r6, [r8, #0x0C]
+ bic r6, r6, #0x04
+ str r6, [r8, #0x0C]
b cont
use_podf:
@@ -100,7 +103,9 @@ cont:
/* Switch to 24MHz or use ARM_PODF. */
cmp r7, #0x0
bne use_podf1
- str r6, [r2, #0x08]
+ /* Set pll1_sw_clk to run from STEP_CLK. */
+ orr r6, r6, #0x04
+ str r6, [r8, #0x0C]
b DO_WFI
use_podf1:
str r6, [r8, #0x10]
@@ -124,8 +129,11 @@ DO_WFI:
mov r4, #0x0
cmp r7, #0x0
bne use_podf2
- ldr r6, =(1 << 16)
- str r6, [r2, #0x08]
+ /* Set pll1_sw_clk to run from STEP_CLK. */
+ ldr r6, [r8, #0x0C]
+ orr r6, r6, #0x04
+ str r6, [r8, #0x0C]
+
b cont1
use_podf2:
@@ -137,7 +145,7 @@ cont1:
DONE:
- pop {r4,r5, r6, r7, r8}
+ pop {r4,r5, r6, r7, r8, r9}
/* Restore registers */
mov pc, lr
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index b9efbb64c8f9..ebc1ca1ee3cc 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -57,6 +57,7 @@ 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 mx6_wait(void *num_cpu_idle_lock, void *num_cpu_idle, \
int wait_arm_podf, int cur_arm_podf);
@@ -64,6 +65,7 @@ extern bool enable_wait_mode;
extern int low_bus_freq_mode;
extern int audio_bus_freq_mode;
extern bool mem_clk_on_in_wait;
+extern int chip_rev;
void gpc_set_wakeup(unsigned int irq[4])
{
@@ -201,6 +203,14 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
*/
reg = __raw_readl(MXC_CCM_CGPR);
reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
+ if (!cpu_is_mx6sl()) {
+ /*
+ * For MX6QTO1.2 or later and MX6DLTO1.1 or later,
+ * ensure that the CCM_CGPR bit 17 is cleared before
+ * dormant mode is entered.
+ */
+ reg &= ~MXC_CCM_CGPR_WAIT_MODE_FIX;
+ }
__raw_writel(reg, MXC_CCM_CGPR);
}
}
@@ -209,56 +219,122 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
extern int tick_broadcast_oneshot_active(void);
- void arch_idle(void)
+void arch_idle_single_core(void)
{
- if (enable_wait_mode) {
- u32 reg;
- int cpu = smp_processor_id();
- *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0;
- mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
- if (arm_mem_clked_in_wait || mem_clk_on_in_wait) {
+ u32 reg;
+
+ if (cpu_is_mx6dl() && chip_rev > IMX_CHIP_REVISION_1_0) {
+ /*
+ * MX6DLS TO1.1 has the HW fix for the WAIT mode issue.
+ * Ensure that the CGPR bit 17 is set to enable the fix.
+ */
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ cpu_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;
+ 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))
+ ;
+ cpu_do_idle();
- cpu_do_idle();
- } else if (num_possible_cpus() == 1) {
- /* We can directly use the divider to drop the ARM
- * core freq in a single core environment.
- */
- u32 podf = wait_mode_arm_podf;
- /* Set the ARM_PODF to get the max freq possible
- * to avoid the WAIT mode issue when IPG is at 66MHz.
- */
- if (low_bus_freq_mode)
- podf = 7;
+ __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
+ }
+}
- __raw_writel(podf, MXC_CCM_CACRR);
- while (__raw_readl(MXC_CCM_CDHIPR))
- ;
- cpu_do_idle();
+void arch_idle_with_workaround(cpu)
+{
+ u32 reg;
+ u32 podf = wait_mode_arm_podf;
+
+ *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0;
+
+ if (low_bus_freq_mode || audio_bus_freq_mode)
+ /* In case when IPG is at 12MHz, we need to ensure that
+ * ARM is at 24MHz, as the max freq ARM can run at is
+ *~28.8MHz.
+ */
+ podf = 0;
+
+ mx6_wait((void *)&num_cpu_idle_lock,
+ (void *)&num_cpu_idle,
+ podf, cur_arm_podf - 1);
+
+}
+
+void arch_idle_multi_core(void)
+{
+ u32 reg;
+ int cpu = smp_processor_id();
- __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
- } else {
#ifdef CONFIG_LOCAL_TIMERS
- if (!tick_broadcast_oneshot_active()
- || !tick_oneshot_mode_active())
- return;
+ if (!tick_broadcast_oneshot_active()
+ || !tick_oneshot_mode_active())
+ return;
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
#endif
- if (low_bus_freq_mode || audio_bus_freq_mode)
- mx6_wait((void *)&num_cpu_idle_lock,
- (void *)&num_cpu_idle,
- 7, cur_arm_podf - 1);
- else
- mx6_wait((void *)&num_cpu_idle_lock,
- (void *)&num_cpu_idle,
- wait_mode_arm_podf, cur_arm_podf - 1);
+ /* iMX6Q and iMX6DL */
+ if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) ||
+ (cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) {
+ /*
+ * This code should only be executed on MX6QTO1.2 or later
+ * and MX6DL TO1.1 or later.
+ * These chips have the HW fix for the WAIT mode issue.
+ * Ensure that the CGPR bit 17 is set to enable the fix.
+ */
+
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ cpu_do_idle();
+ } else
+ arch_idle_with_workaround(cpu);
#ifdef CONFIG_LOCAL_TIMERS
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
#endif
- }
+
+}
+
+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)) {
+ u32 reg;
+ /*
+ * MX6SL, MX6Q (TO1.2 or later) and
+ * MX6DL (TO1.1 or later) have a bit in CCM_CGPR that
+ * when cleared keeps the clocks to memories ON
+ * when ARM is in WFI. This mode can be used when
+ * IPG clock is very low (12MHz) and the ARM:IPG ratio
+ * perhaps cannot be maintained.
+ */
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg &= ~MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ cpu_do_idle();
+ } else if (num_possible_cpus() == 1)
+ /* iMX6SL or iMX6DLS */
+ arch_idle_single_core();
+ else
+ arch_idle_multi_core();
} else {
mxc_cpu_lp_set(WAIT_CLOCKED);
cpu_do_idle();
diff --git a/arch/arm/mach-mx6/usb.h b/arch/arm/mach-mx6/usb.h
index 145cfbfcc728..f796e7dad87c 100644
--- a/arch/arm/mach-mx6/usb.h
+++ b/arch/arm/mach-mx6/usb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-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
@@ -29,7 +29,7 @@ extern int gpio_usbotg_utmi_active(void);
extern void gpio_usbotg_utmi_inactive(void);
extern void __init mx6_usb_dr_init(void);
-extern void __init mx6_usb_h1_init(void);
+extern bool usb_icbug_swfix_need(void);
extern void __init mx6_usb_h2_init(void);
extern void __init mx6_usb_h3_init(void);
@@ -38,6 +38,7 @@ extern void mx6_set_host3_vbus_func(driver_vbus_func);
extern void mx6_set_host2_vbus_func(driver_vbus_func);
extern void mx6_set_host1_vbus_func(driver_vbus_func);
extern void mx6_set_otghost_vbus_func(driver_vbus_func);
+extern void mx6_set_usb_host1_vbus_func(driver_vbus_func *driver_vbus);
extern struct platform_device anatop_thermal_device;
extern struct platform_device mxc_usbdr_otg_device;
extern struct platform_device mxc_usbdr_udc_device;
@@ -60,3 +61,15 @@ extern struct platform_device mxc_usbh1_wakeup_device;
#endif
extern void __iomem *imx_otg_base;
+#define imx_fsl_usb2_wakeup_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .irq_phy = soc ## _INT_USB_PHY ## _id, \
+ .irq_core = soc ## _INT_USB_ ## hs, \
+ }
+#define imx_mxc_ehci_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _USB_ ## hs ## _BASE_ADDR, \
+ .irq = soc ## _INT_USB_ ## hs, \
+ }
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index dbd1e67b3fc5..1efac33aa7fc 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -164,8 +164,9 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
}
if (!usb_icbug_swfix_need())
- __raw_writel(((1 << 17) | (1 << 18)),
- phy_reg + HW_USBPHY_IP_SET);
+ __raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
+ if (cpu_is_mx6sl())
+ __raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
return 0;
}
/* Notes: configure USB clock*/
@@ -380,7 +381,7 @@ static void usbotg_wakeup_event_clear(void)
#ifdef CONFIG_USB_EHCI_ARC_OTG
/* Beginning of host related operation for DR port */
-static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+static void _host_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
u32 tmp;
@@ -419,7 +420,7 @@ static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
fsl_platform_otg_set_usb_phy_dis(pdata, 0);
}
-static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+static void _host_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
{
u32 index = 0;
@@ -438,6 +439,25 @@ static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
udelay(500);
fsl_platform_otg_set_usb_phy_dis(pdata, 1);
}
+static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+}
+
+static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+}
static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
{
@@ -579,11 +599,11 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.operating_mode = DR_HOST_MODE;
dr_utmi_config.wake_up_enable = _host_wakeup_enable;
if (usb_icbug_swfix_need()) {
+ dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend_swfix;
+ dr_utmi_config.platform_rh_resume = _host_platform_rh_resume_swfix;
+ } else {
dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend;
dr_utmi_config.platform_rh_resume = _host_platform_rh_resume;
- } else {
- dr_utmi_config.platform_rh_suspend = NULL;
- dr_utmi_config.platform_rh_resume = NULL;
}
dr_utmi_config.platform_set_disconnect_det = fsl_platform_otg_set_usb_phy_dis;
dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c
index bff9a29aef02..92ef0ec3c3f5 100644
--- a/arch/arm/mach-mx6/usb_h1.c
+++ b/arch/arm/mach-mx6/usb_h1.c
@@ -34,7 +34,6 @@
static struct clk *usb_oh3_clk;
extern int clk_get_usecount(struct clk *clk);
static struct fsl_usb2_platform_data usbh1_config;
-extern bool usb_icbug_swfix_need(void);
static void fsl_platform_h1_set_usb_phy_dis(
struct fsl_usb2_platform_data *pdata, bool enable)
@@ -126,8 +125,9 @@ static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
__raw_writel(tmp, phy_reg + HW_USBPHY_CTRL);
if (!usb_icbug_swfix_need())
- __raw_writel(((1 << 17) | (1 << 18)),
- phy_reg + HW_USBPHY_IP_SET);
+ __raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
+ if (cpu_is_mx6sl())
+ __raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
return 0;
}
static int fsl_usb_host_init_ext(struct platform_device *pdev)
@@ -170,11 +170,6 @@ static void usbh1_clock_gate(bool on)
}
}
-void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus)
-{
- usbh1_config.platform_driver_vbus = driver_vbus;
-}
-
static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
@@ -199,7 +194,7 @@ static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
}
}
-static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+static void usbh1_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
u32 tmp;
@@ -238,7 +233,7 @@ static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
fsl_platform_h1_set_usb_phy_dis(pdata, 0);
}
-static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
{
u32 index = 0;
@@ -258,6 +253,26 @@ static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
fsl_platform_h1_set_usb_phy_dis(pdata, 1);
}
+static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+}
+
+static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+}
+
static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
{
u32 tmp;
@@ -347,18 +362,49 @@ static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = {
.usb_wakeup_exhandle = usbh1_wakeup_event_clear,
};
-void __init mx6_usb_h1_init(void)
+static struct platform_device *pdev, *pdev_wakeup;
+static driver_vbus_func mx6_set_usb_host1_vbus;
+
+static int __init mx6_usb_h1_init(void)
{
- struct platform_device *pdev, *pdev_wakeup;
static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)};
+ struct imx_fsl_usb2_wakeup_data imx6sl_fsl_hs_wakeup_data[] = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)};
+ struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = {
+ imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)};
+ struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = {
+ imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)};
+
+ mx6_set_usb_host1_vbus_func(&mx6_set_usb_host1_vbus);
+ if (mx6_set_usb_host1_vbus)
+ mx6_set_usb_host1_vbus(true);
+
+ /* Some phy and power's special controls for host1
+ * 1. The external charger detector needs to be disabled
+ * or the signal at DP will be poor
+ * 2. The PLL's power and output to usb for host 1
+ * is totally controlled by IC, so the Software only needs
+ * to enable them at initializtion.
+ */
+ __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B \
+ | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
+ anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \
+ | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
+ | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
if (usb_icbug_swfix_need()) {
+ usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend_swfix;
+ usbh1_config.platform_rh_resume = usbh1_platform_rh_resume_swfix;
+ } else {
usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend;
usbh1_config.platform_rh_resume = usbh1_platform_rh_resume;
- } else {
- usbh1_config.platform_rh_suspend = NULL;
- usbh1_config.platform_rh_resume = NULL;
}
if (cpu_is_mx6sl())
pdev = imx6sl_add_fsl_ehci_hs(1, &usbh1_config);
@@ -371,21 +417,28 @@ void __init mx6_usb_h1_init(void)
pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
(struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
+ return 0;
+}
+module_init(mx6_usb_h1_init);
- /* Some phy and power's special controls for host1
- * 1. The external charger detector needs to be disabled
- * or the signal at DP will be poor
- * 2. The PLL's power and output to usb for host 1
- * is totally controlled by IC, so the Software only needs
- * to enable them at initializtion.
- */
- __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B \
- | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
- anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
+static void __exit mx6_usb_h1_exit(void)
+{
+ static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+
+ platform_device_unregister(pdev);
+ platform_device_unregister(pdev_wakeup);
__raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
- anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
__raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \
| BM_ANADIG_USB2_PLL_480_CTRL_POWER \
| BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
- anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+ if (mx6_set_usb_host1_vbus)
+ mx6_set_usb_host1_vbus(false);
+
+ return ;
}
+module_exit(mx6_usb_h1_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
index b31970c667d2..765f05e23712 100755
--- a/arch/arm/plat-mxc/cpufreq.c
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -56,6 +56,7 @@ extern struct regulator *cpu_regulator;
extern int dvfs_core_is_active;
extern struct cpu_op *(*get_cpu_op)(int *op);
extern int low_bus_freq_mode;
+extern int audio_bus_freq_mode;
extern int high_bus_freq_mode;
extern int set_low_bus_freq(void);
extern int set_high_bus_freq(int high_bus_speed);
@@ -85,7 +86,7 @@ int set_cpu_freq(int freq)
#endif
/*Set the voltage for the GP domain. */
if (freq > org_cpu_rate) {
- if (low_bus_freq_mode)
+ if (low_bus_freq_mode || audio_bus_freq_mode)
set_high_bus_freq(0);
ret = regulator_set_voltage(cpu_regulator, gp_volt,
gp_volt);
@@ -108,7 +109,8 @@ int set_cpu_freq(int freq)
printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n");
return ret;
}
- if (low_freq_bus_used() && !low_bus_freq_mode)
+ if (low_freq_bus_used() &&
+ !(low_bus_freq_mode || audio_bus_freq_mode))
set_low_bus_freq();
}
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
index 986b766fabde..3dacd287c6b8 100644
--- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
@@ -52,3 +52,4 @@ struct platform_device *__init imx_add_fsl_usb2_wakeup(
res, ARRAY_SIZE(res),
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
}
+EXPORT_SYMBOL(imx_add_fsl_usb2_wakeup);
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
index c39f6d7561c6..2b9cdff2ff97 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
@@ -83,6 +83,7 @@ struct platform_device *__init imx_add_mxc_ehci(
res, ARRAY_SIZE(res),
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
}
+EXPORT_SYMBOL(imx_add_mxc_ehci);
/* FSL internal non-upstream code */
struct platform_device *__init imx_add_fsl_ehci(
@@ -104,3 +105,4 @@ struct platform_device *__init imx_add_fsl_ehci(
res, ARRAY_SIZE(res),
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
}
+EXPORT_SYMBOL(imx_add_fsl_ehci);
diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
index ba00959c19fa..3fccb3be9e15 100644
--- a/arch/arm/plat-mxc/include/mach/dma.h
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -45,6 +45,7 @@ enum sdma_peripheral_type {
IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */
IMX_DMATYPE_ASRC, /* ASRC */
IMX_DMATYPE_ESAI, /* ESAI */
+ IMX_DMATYPE_HDMI,
};
enum imx_dma_prio {
@@ -58,6 +59,7 @@ struct imx_dma_data {
int dma_request_p2p;
enum sdma_peripheral_type peripheral_type;
int priority;
+ void *private;
};
struct imx_pcm_dma_params {
diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h
index a145c56b649d..cee7fe490188 100644
--- a/arch/arm/plat-mxc/include/mach/sdma.h
+++ b/arch/arm/plat-mxc/include/mach/sdma.h
@@ -45,6 +45,7 @@ struct sdma_script_start_addrs {
s32 ram_code_start_addr;
s32 mcu_2_ssish_addr;
s32 ssish_2_mcu_addr;
+ s32 hdmi_dma_addr;
};
/**
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
index b18f5239c8b9..97d963a54a54 100755
--- a/arch/arm/plat-mxc/usb_common.c
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -49,8 +49,12 @@
#include <mach/arc_otg.h>
#include <mach/hardware.h>
#include <mach/mxc.h>
+typedef void (*driver_vbus_func)(bool);
void __iomem *imx_otg_base;
+static driver_vbus_func s_driver_vbus;
+
+EXPORT_SYMBOL(imx_otg_base);
#define MXC_NUMBER_USB_TRANSCEIVER 6
struct fsl_xcvr_ops *g_xc_ops[MXC_NUMBER_USB_TRANSCEIVER] = { NULL };
@@ -59,10 +63,26 @@ bool usb_icbug_swfix_need(void)
{
if (cpu_is_mx6sl())
return false;
- else
- return true;
+ else if ((mx6q_revision() > IMX_CHIP_REVISION_1_1))
+ return false;
+ else if ((mx6dl_revision() > IMX_CHIP_REVISION_1_0))
+ return false;
+ return true;
+}
+EXPORT_SYMBOL(usb_icbug_swfix_need);
+
+void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus)
+{
+ s_driver_vbus = driver_vbus;
}
+void mx6_set_usb_host1_vbus_func(driver_vbus_func *driver_vbus)
+{
+ *driver_vbus = s_driver_vbus;
+}
+EXPORT_SYMBOL(mx6_set_usb_host1_vbus_func);
+
+
enum fsl_usb2_modes get_usb_mode(struct fsl_usb2_platform_data *pdata)
{
enum fsl_usb2_modes mode;
diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c
index 4704eae91a51..e67c2219e52d 100755
--- a/arch/arm/plat-mxc/usb_wakeup.c
+++ b/arch/arm/plat-mxc/usb_wakeup.c
@@ -32,6 +32,7 @@
struct wakeup_ctrl {
int wakeup_irq;
int usb_irq;
+ bool thread_close;
struct fsl_usb2_wakeup_platform_data *pdata;
struct task_struct *thread;
struct completion event;
@@ -145,12 +146,18 @@ static int wakeup_event_thread(void *param)
{
struct wakeup_ctrl *ctrl = (struct wakeup_ctrl *)param;
struct sched_param sch_param = {.sched_priority = 1};
+ u32 timeout = 0;
sched_setscheduler(current, SCHED_RR, &sch_param);
while (1) {
wait_for_completion_interruptible(&ctrl->event);
- if (kthread_should_stop())
+ if (ctrl->thread_close) {
+ while (!kthread_should_stop() && (timeout < 1000)) {
+ timeout++;
+ msleep(1);
+ }
break;
+ }
wakeup_event_handler(ctrl);
enable_irq(ctrl->wakeup_irq);
if ((ctrl->usb_irq > 0) && (ctrl->wakeup_irq != ctrl->usb_irq))
@@ -184,6 +191,7 @@ static int wakeup_dev_probe(struct platform_device *pdev)
*/
ctrl->wakeup_irq = platform_get_irq(pdev, 1);
ctrl->usb_irq = platform_get_irq(pdev, 1);
+ ctrl->thread_close = false;
if (ctrl->wakeup_irq != ctrl->usb_irq)
interrupt_flag = IRQF_DISABLED;
else
@@ -210,6 +218,7 @@ error1:
static int wakeup_dev_exit(struct platform_device *pdev)
{
if (g_ctrl->thread) {
+ g_ctrl->thread_close = true;
complete(&g_ctrl->event);
kthread_stop(g_ctrl->thread);
}