summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mx6')
-rw-r--r--arch/arm/mach-mx6/Kconfig7
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c17
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.h6
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c18
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.h4
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c17
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c16
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.h4
-rw-r--r--arch/arm/mach-mx6/clock.c29
-rw-r--r--arch/arm/mach-mx6/system.c51
10 files changed, 142 insertions, 27 deletions
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 59d8ab313f73..df954b40d8e8 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -319,4 +319,11 @@ config MACH_IMX_BLUETOOTH_RFKILL
---help---
Say Y to get the standard rfkill interface of Bluetooth
+config MX6_ENET_IRQ_TO_GPIO
+ bool "Route ENET interrupts to GPIO"
+ default n
+ help
+ Enabling this will direct all the ENET interrupts to a board specific GPIO.
+ This will allow the system to enter WAIT mode when ENET is active.
+
endif
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index d627324d77ab..8a2687d04f36 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -156,6 +156,12 @@
#define MX6_ARM2_CAN2_STBY MX6_ARM2_IO_EXP_GPIO2(1)
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
@@ -388,6 +394,9 @@ static struct fec_platform_data fec_data __initdata = {
.init = mx6_arm2_fec_phy_init,
.power_hibernate = mx6_arm2_fec_power_hibernate,
.phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
};
static int mx6_arm2_spi_cs[] = {
@@ -2200,8 +2209,14 @@ static void __init mx6_arm2_init(void)
imx6q_add_anatop_thermal_imx(1, &mx6_arm2_anatop_thermal_data);
- if (!esai_record)
+ if (!esai_record) {
imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+ }
imx6q_add_pm_imx(0, &mx6_arm2_pm_data);
imx6q_add_sdhci_usdhc_imx(3, &mx6_arm2_sd4_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.h b/arch/arm/mach-mx6/board-mx6q_arm2.h
index 8295c6e36905..2a6a2052b3f9 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.h
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013 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
@@ -183,10 +183,14 @@ static iomux_v3_cfg_t mx6q_arm2_pads[] = {
/* USBOTG ID pin */
MX6Q_PAD_GPIO_1__USBOTG_ID,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
/* MLB150 */
MX6Q_PAD_GPIO_3__MLB_MLBCLK,
MX6Q_PAD_GPIO_6__MLB_MLBSIG,
MX6Q_PAD_GPIO_2__MLB_MLBDAT,
+#endif
};
static iomux_v3_cfg_t mx6q_arm2_i2c3_pads[] = {
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
index 853ecf563222..45f4af592ab9 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -115,6 +115,13 @@
#define SABREAUTO_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
#define SABREAUTO_MAX7310_3_BASE_ADDR IMX_GPIO_NR(8, 16)
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
#define SABREAUTO_IO_EXP_GPIO1(x) (SABREAUTO_MAX7310_1_BASE_ADDR + (x))
#define SABREAUTO_IO_EXP_GPIO2(x) (SABREAUTO_MAX7310_2_BASE_ADDR + (x))
#define SABREAUTO_IO_EXP_GPIO3(x) (SABREAUTO_MAX7310_3_BASE_ADDR + (x))
@@ -409,6 +416,9 @@ static struct fec_platform_data fec_data __initdata = {
.init = mx6q_sabreauto_fec_phy_init,
.power_hibernate = mx6q_sabreauto_fec_power_hibernate,
.phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
};
static int mx6q_sabreauto_spi_cs[] = {
@@ -1723,9 +1733,15 @@ static void __init mx6_board_init(void)
imx6q_add_anatop_thermal_imx(1, &mx6q_sabreauto_anatop_thermal_data);
- if (!can0_enable)
+ if (!can0_enable) {
imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+ }
imx6q_add_pm_imx(0, &mx6q_sabreauto_pm_data);
imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabreauto_sd3_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.h b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
index 41d0c560f416..e4d62f1baaa5 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.h
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
@@ -208,10 +208,14 @@ static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
/* HDMI */
MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
/* MLB150 */
MX6Q_PAD_ENET_TXD1__MLB_MLBCLK,
MX6Q_PAD_GPIO_6__MLB_MLBSIG,
MX6Q_PAD_GPIO_2__MLB_MLBDAT,
+#endif
};
static iomux_v3_cfg_t mx6q_sabreauto_can0_pads[] = {
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index 24914fe6904b..338c16ab6a52 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -94,6 +94,13 @@
#define MX6Q_SABRELITE_CSI0_RST IMX_GPIO_NR(1, 8)
#define MX6Q_SABRELITE_CSI0_PWN IMX_GPIO_NR(1, 6)
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
#define MX6Q_SABRELITE_SD3_WP_PADCFG (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
@@ -322,7 +329,9 @@ static iomux_v3_cfg_t mx6q_sabrelite_csi0_sensor_pads[] = {
MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
MX6Q_PAD_GPIO_6__GPIO_1_6, /* J5 - Camera GP */
+#endif
MX6Q_PAD_GPIO_8__GPIO_1_8, /* J5 - Camera Reset */
MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* J5 - Camera GP */
MX6Q_PAD_NANDF_D5__GPIO_2_5, /* J16 - MIPI GP */
@@ -468,6 +477,9 @@ static int mx6q_sabrelite_fec_phy_init(struct phy_device *phydev)
static struct fec_platform_data fec_data __initdata = {
.init = mx6q_sabrelite_fec_phy_init,
.phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
};
static int mx6q_sabrelite_spi_cs[] = {
@@ -1259,6 +1271,11 @@ static void __init mx6_sabrelite_board_init(void)
imx6q_add_anatop_thermal_imx(1, &mx6q_sabrelite_anatop_thermal_data);
imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
imx6q_add_pm_imx(0, &mx6q_sabrelite_pm_data);
imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabrelite_sd4_data);
imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabrelite_sd3_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index 2b8a1bedc17b..9971ff55a765 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -201,6 +201,13 @@
#define SABRESD_ELAN_RST IMX_GPIO_NR(3, 8)
#define SABRESD_ELAN_INT IMX_GPIO_NR(3, 28)
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
static struct clk *sata_clk;
static struct clk *clko;
static int mma8451_position;
@@ -303,6 +310,9 @@ static int mx6q_sabresd_fec_phy_init(struct phy_device *phydev)
static struct fec_platform_data fec_data __initdata = {
.init = mx6q_sabresd_fec_phy_init,
.phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
};
static int mx6q_sabresd_spi_cs[] = {
@@ -1955,6 +1965,12 @@ static void __init mx6_sabresd_board_init(void)
imx6q_add_anatop_thermal_imx(1, &mx6q_sabresd_anatop_thermal_data);
imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+
imx6q_add_pm_imx(0, &mx6q_sabresd_pm_data);
/* Move sd4 to first because sd4 connect to emmc.
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.h b/arch/arm/mach-mx6/board-mx6q_sabresd.h
index 73ee909e50ef..b2bb8c923f0f 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.h
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.h
@@ -132,9 +132,13 @@ static iomux_v3_cfg_t mx6q_sabresd_pads[] = {
MX6Q_PAD_KEY_COL3__I2C2_SCL,
MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
/* I2C3 */
MX6Q_PAD_GPIO_3__I2C3_SCL, /* GPIO1[3] */
MX6Q_PAD_GPIO_6__I2C3_SDA,
+#endif
/* DISPLAY */
MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index c45fa2cafe71..574b142eb758 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -51,6 +51,7 @@ extern int lp_med_freq;
extern int wait_mode_arm_podf;
extern int lp_audio_freq;
extern int cur_arm_podf;
+extern bool enet_is_active;
void __iomem *apll_base;
@@ -1153,7 +1154,11 @@ static int _clk_pll_mlb_main_enable(struct clk *clk)
reg = __raw_readl(pllbase);
reg &= ~ANADIG_PLL_BYPASS;
- reg = 0x0da20800;
+ reg = (0x3 << ANADIG_PLL_MLB_FLT_RES_CFG_OFFSET) |
+ (0x3 << ANADIG_PLL_MLB_RX_CLK_DELAY_CFG_OFFSET) |
+ (0x2 << ANADIG_PLL_MLB_VDDD_DELAY_CFG_OFFSET) |
+ (0x1 << ANADIG_PLL_MLB_VDDA_DELAY_CFG_OFFSET) |
+ (ANADIG_PLL_HOLD_RING_OFF);
__raw_writel(reg, pllbase);
return 0;
@@ -3724,6 +3729,23 @@ static unsigned long _clk_enet_get_rate(struct clk *clk)
return 500000000 / div;
}
+static int _clk_enet_enable(struct clk *clk)
+{
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ enet_is_active = true;
+#endif
+ _clk_enable(clk);
+ return 0;
+}
+
+static void _clk_enet_disable(struct clk *clk)
+{
+ _clk_disable(clk);
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ enet_is_active = false;
+#endif
+}
+
static struct clk enet_clk[] = {
{
__INIT_CLK_DEBUG(enet_clk)
@@ -3731,8 +3753,8 @@ static struct clk enet_clk[] = {
.parent = &pll8_enet_main_clk,
.enable_reg = MXC_CCM_CCGR1,
.enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
- .enable = _clk_enable,
- .disable = _clk_disable,
+ .enable = _clk_enet_enable,
+ .disable = _clk_enet_disable,
.set_rate = _clk_enet_set_rate,
.get_rate = _clk_enet_get_rate,
.secondary = &enet_clk[1],
@@ -4889,6 +4911,7 @@ static int _clk_mlb_set_parent(struct clk *clk, struct clk *parent)
static struct clk mlb150_clk = {
__INIT_CLK_DEBUG(mlb150_clk)
.id = 0,
+ .secondary = &ocram_clk,
.set_parent = _clk_mlb_set_parent,
.enable_reg = MXC_CCM_CCGR3,
.enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index f6ffa2999ed2..4990a4a0abbb 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;
volatile unsigned int num_cpu_idle_lock = 0x0;
int wait_mode_arm_podf;
int cur_arm_podf;
+bool enet_is_active;
void arch_idle_with_workaround(int cpu);
extern void *mx6sl_wfi_iram_base;
@@ -350,7 +351,7 @@ void arch_idle_single_core(void)
}
}
-void arch_idle_with_workaround(cpu)
+void arch_idle_with_workaround(int cpu)
{
u32 podf = wait_mode_arm_podf;
@@ -369,18 +370,10 @@ void arch_idle_with_workaround(cpu)
}
-void arch_idle_multi_core(void)
+void arch_idle_multi_core(int cpu)
{
u32 reg;
- int cpu = smp_processor_id();
-#ifdef CONFIG_LOCAL_TIMERS
- if (!tick_broadcast_oneshot_active()
- || !tick_oneshot_mode_active())
- return;
-
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
-#endif
/* iMX6Q and iMX6DL */
if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) ||
(cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) {
@@ -398,24 +391,37 @@ void arch_idle_multi_core(void)
ca9_do_idle();
} else
arch_idle_with_workaround(cpu);
-#ifdef CONFIG_LOCAL_TIMERS
- clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
-#endif
-
}
void arch_idle(void)
{
+ int cpu = smp_processor_id();
+
if (enable_wait_mode) {
- mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+#ifdef CONFIG_LOCAL_TIMERS
+ if (!tick_broadcast_oneshot_active()
+ || !tick_oneshot_mode_active())
+ return;
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+#endif
+ if (enet_is_active)
+ /* Don't allow the chip to enter WAIT mode if enet is active
+ * and the GPIO workaround for ENET interrupts is not used,
+ * since all ENET interrupts donot wake up the SOC.
+ */
+ mxc_cpu_lp_set(WAIT_CLOCKED);
+ else
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
if (mem_clk_on_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
+ * 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);
@@ -427,8 +433,11 @@ void arch_idle(void)
/* iMX6SL or iMX6DLS */
arch_idle_single_core();
else
- arch_idle_multi_core();
- } else {
+ arch_idle_multi_core(cpu);
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+#endif
+ } else {
mxc_cpu_lp_set(WAIT_CLOCKED);
ca9_do_idle();
}