diff options
37 files changed, 600 insertions, 34 deletions
| diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 93d595a7477a..4f8f3a4e4e0d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -365,6 +365,7 @@ config ARCH_MXC  	select GENERIC_CLOCKEVENTS  	select ARCH_REQUIRE_GPIOLIB  	select CLKDEV_LOOKUP +	select HAVE_SCHED_CLOCK  	help  	  Support for Freescale MXC/iMX-based family of processors diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5eec099e0c72..56b930a13443 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -255,6 +255,7 @@ config MACH_IMX27_VISSTRIM_M10  	bool "Vista Silicon i.MX27 Visstrim_m10"  	select SOC_IMX27  	select IMX_HAVE_PLATFORM_IMX_I2C +	select IMX_HAVE_PLATFORM_IMX_SSI  	select IMX_HAVE_PLATFORM_IMX_UART  	select IMX_HAVE_PLATFORM_MXC_MMC  	select IMX_HAVE_PLATFORM_MXC_EHCI diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c index cb705c28de02..6269053505f7 100644 --- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c @@ -34,6 +34,7 @@  #include <mach/mx25.h>  #include <mach/imx-uart.h>  #include <mach/audmux.h> +#include <mach/esdhc.h>  #include "devices-imx25.h" @@ -242,6 +243,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {  	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,  }; +static struct esdhc_platform_data sd1_pdata = { +	.cd_gpio = GPIO_SD1CD, +	.wp_gpio = -EINVAL, +}; +  /*   * system init for baseboard usage. Will be called by cpuimx25 init.   * @@ -275,7 +281,7 @@ void __init eukrea_mbimxsd25_baseboard_init(void)  	imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);  	imx25_add_flexcan1(NULL); -	imx25_add_sdhci_esdhc_imx(0, NULL); +	imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);  	gpio_request(GPIO_LED1, "LED1");  	gpio_direction_output(GPIO_LED1, 1); diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c index 80761474c0f8..2e288b38b4ad 100644 --- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c @@ -43,6 +43,7 @@  #include <mach/ipu.h>  #include <mach/mx3fb.h>  #include <mach/audmux.h> +#include <mach/esdhc.h>  #include "devices-imx35.h"  #include "devices.h" @@ -163,11 +164,14 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {  	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,  	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,  	MX35_PAD_SD1_DATA3__ESDHC1_DAT3, +	/* SD1 CD */ +	MX35_PAD_LD18__GPIO3_24,  };  #define GPIO_LED1	IMX_GPIO_NR(3, 29)  #define GPIO_SWITCH1	IMX_GPIO_NR(3, 25) -#define GPIO_LCDPWR	(4) +#define GPIO_LCDPWR	IMX_GPIO_NR(1, 4) +#define GPIO_SD1CD	IMX_GPIO_NR(3, 24)  static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,  				   unsigned int power) @@ -254,6 +258,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {  	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,  }; +static struct esdhc_platform_data sd1_pdata = { +	.cd_gpio = GPIO_SD1CD, +	.wp_gpio = -EINVAL, +}; +  /*   * system init for baseboard usage. Will be called by cpuimx35 init.   * @@ -289,7 +298,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)  	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);  	imx35_add_flexcan1(NULL); -	imx35_add_sdhci_esdhc_imx(0, NULL); +	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);  	gpio_request(GPIO_LED1, "LED1");  	gpio_direction_output(GPIO_LED1, 1); @@ -301,7 +310,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)  	gpio_request(GPIO_LCDPWR, "LCDPWR");  	gpio_direction_output(GPIO_LCDPWR, 1); -	gpio_free(GPIO_LCDPWR);  	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,  				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices)); diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c index b3ecfb22d241..036ba1a4704b 100644 --- a/arch/arm/mach-mx3/mach-pcm043.c +++ b/arch/arm/mach-mx3/mach-pcm043.c @@ -40,6 +40,7 @@  #include <mach/mx3fb.h>  #include <mach/ulpi.h>  #include <mach/audmux.h> +#include <mach/esdhc.h>  #include "devices-imx35.h"  #include "devices.h" @@ -217,11 +218,15 @@ static iomux_v3_cfg_t pcm043_pads[] = {  	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,  	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,  	MX35_PAD_SD1_DATA3__ESDHC1_DAT3, +	MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */ +	MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */  };  #define AC97_GPIO_TXFS	IMX_GPIO_NR(2, 31)  #define AC97_GPIO_TXD	IMX_GPIO_NR(2, 28)  #define AC97_GPIO_RESET	IMX_GPIO_NR(2, 0) +#define SD1_GPIO_WP	IMX_GPIO_NR(2, 23) +#define SD1_GPIO_CD	IMX_GPIO_NR(2, 24)  static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)  { @@ -346,6 +351,11 @@ static int __init pcm043_otg_mode(char *options)  }  __setup("otg_mode=", pcm043_otg_mode); +static struct esdhc_platform_data sd1_pdata = { +	.wp_gpio = SD1_GPIO_WP, +	.cd_gpio = SD1_GPIO_CD, +}; +  /*   * Board specific initialization.   */ @@ -395,7 +405,7 @@ static void __init pcm043_init(void)  		imx35_add_fsl_usb2_udc(&otg_device_pdata);  	imx35_add_flexcan1(NULL); -	imx35_add_sdhci_esdhc_imx(0, NULL); +	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);  }  static void __init pcm043_timer_init(void) diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 83ee08847d4d..159340da9191 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -165,6 +165,7 @@ config MACH_MX53_LOCO  	select IMX_HAVE_PLATFORM_IMX_I2C  	select IMX_HAVE_PLATFORM_IMX_UART  	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX +	select IMX_HAVE_PLATFORM_GPIO_KEYS  	help  	  Include support for MX53 LOCO platform. This includes specific  	  configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 4f63048be3ca..0b9338cec516 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -3,7 +3,7 @@  #  # Object file lists. -obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o +obj-y   := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o  obj-$(CONFIG_SOC_IMX50) += mm-mx50.o  obj-$(CONFIG_CPU_FREQ_IMX)    += cpu_op-mx51.o diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index b2ecd194e76d..bea4e4135f9d 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -228,13 +228,12 @@ static inline void babbage_fec_reset(void)  	int ret;  	/* reset FEC PHY */ -	ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset"); +	ret = gpio_request_one(BABBAGE_FEC_PHY_RESET, +					GPIOF_OUT_INIT_LOW, "fec-phy-reset");  	if (ret) {  		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);  		return;  	} -	gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0); -	gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);  	msleep(1);  	gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);  } diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c index 7b5735c5ea59..2af3f43f74db 100644 --- a/arch/arm/mach-mx5/board-mx53_evk.c +++ b/arch/arm/mach-mx5/board-mx53_evk.c @@ -34,7 +34,7 @@  #include <mach/imx-uart.h>  #include <mach/iomux-mx53.h> -#define SMD_FEC_PHY_RST		IMX_GPIO_NR(7, 6) +#define MX53_EVK_FEC_PHY_RST	IMX_GPIO_NR(7, 6)  #define EVK_ECSPI1_CS0		IMX_GPIO_NR(2, 30)  #define EVK_ECSPI1_CS1		IMX_GPIO_NR(3, 19) @@ -82,15 +82,14 @@ static inline void mx53_evk_fec_reset(void)  	int ret;  	/* reset FEC PHY */ -	ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset"); +	ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW, +							"fec-phy-reset");  	if (ret) {  		printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);  		return;  	} -	gpio_direction_output(SMD_FEC_PHY_RST, 0); -	gpio_set_value(SMD_FEC_PHY_RST, 0);  	msleep(1); -	gpio_set_value(SMD_FEC_PHY_RST, 1); +	gpio_set_value(MX53_EVK_FEC_PHY_RST, 1);  }  static struct fec_platform_data mx53_evk_fec_pdata = { diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index 0a18f8d23eb0..10a1bea10548 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c @@ -36,6 +36,9 @@  #include "crm_regs.h"  #include "devices-imx53.h" +#define MX53_LOCO_POWER			IMX_GPIO_NR(1, 8) +#define MX53_LOCO_UI1			IMX_GPIO_NR(2, 14) +#define MX53_LOCO_UI2			IMX_GPIO_NR(2, 15)  #define LOCO_FEC_PHY_RST		IMX_GPIO_NR(7, 6)  static iomux_v3_cfg_t mx53_loco_pads[] = { @@ -180,6 +183,27 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {  	MX53_PAD_GPIO_8__GPIO1_8,  }; +#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake)	\ +{								\ +	.gpio		= gpio_num,				\ +	.type		= EV_KEY,				\ +	.code		= ev_code,				\ +	.active_low	= act_low,				\ +	.desc		= "btn " descr,				\ +	.wakeup		= wake,					\ +} + +static const struct gpio_keys_button loco_buttons[] __initconst = { +	GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), +	GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), +	GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0), +}; + +static const struct gpio_keys_platform_data loco_button_data __initconst = { +	.buttons        = loco_buttons, +	.nbuttons       = ARRAY_SIZE(loco_buttons), +}; +  static inline void mx53_loco_fec_reset(void)  {  	int ret; @@ -215,6 +239,7 @@ static void __init mx53_loco_board_init(void)  	imx53_add_imx_i2c(1, &mx53_loco_i2c_data);  	imx53_add_sdhci_esdhc_imx(0, NULL);  	imx53_add_sdhci_esdhc_imx(2, NULL); +	imx_add_gpio_keys(&loco_button_data);  }  static void __init mx53_loco_timer_init(void) diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 652ace413825..fdbc05ed5513 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = {  	.disable = _clk_ccgr_disable_inwait,  }; +static struct clk gpc_dvfs_clk = { +	.enable_reg = MXC_CCM_CCGR5, +	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, +	.enable = _clk_ccgr_enable, +	.disable = _clk_ccgr_disable, +}; +  static struct clk gpt_32k_clk = {  	.id = 0,  	.parent = &ckil_clk, @@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = {  	_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)  	_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)  	_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) +	_REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)  };  static struct clk_lookup mx53_lookups[] = { @@ -1511,6 +1519,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,  	clk_enable(&iim_clk);  	mx51_revision();  	clk_disable(&iim_clk); +	mx51_display_revision();  	/* move usb_phy_clk to 24MHz */  	clk_set_parent(&usb_phy1_clk, &osc_clk); diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index df46b5e60857..472bdfab2e55 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -21,6 +21,7 @@  static int cpu_silicon_rev = -1;  #define IIM_SREV 0x24 +#define MX50_HW_ADADIG_DIGPROG	0xB0  static int get_mx51_srev(void)  { @@ -51,6 +52,26 @@ int mx51_revision(void)  }  EXPORT_SYMBOL(mx51_revision); +void mx51_display_revision(void) +{ +	int rev; +	char *srev; +	rev = mx51_revision(); + +	switch (rev) { +	case IMX_CHIP_REVISION_2_0: +		srev = IMX_CHIP_REVISION_2_0_STRING; +		break; +	case IMX_CHIP_REVISION_3_0: +		srev = IMX_CHIP_REVISION_3_0_STRING; +		break; +	default: +		srev = IMX_CHIP_REVISION_UNKNOWN_STRING; +	} +	printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev); +} +EXPORT_SYMBOL(mx51_display_revision); +  #ifdef CONFIG_NEON  /* @@ -107,6 +128,44 @@ int mx53_revision(void)  }  EXPORT_SYMBOL(mx53_revision); +static int get_mx50_srev(void) +{ +	void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K); +	u32 rev; + +	if (!anatop) { +		cpu_silicon_rev = -EINVAL; +		return 0; +	} + +	rev = readl(anatop + MX50_HW_ADADIG_DIGPROG); +	rev &= 0xff; + +	iounmap(anatop); +	if (rev == 0x0) +		return IMX_CHIP_REVISION_1_0; +	else if (rev == 0x1) +		return IMX_CHIP_REVISION_1_1; +	return 0; +} + +/* + * Returns: + *	the silicon revision of the cpu + *	-EINVAL - not a mx50 + */ +int mx50_revision(void) +{ +	if (!cpu_is_mx50()) +		return -EINVAL; + +	if (cpu_silicon_rev == -1) +		cpu_silicon_rev = get_mx50_srev(); + +	return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx50_revision); +  static int __init post_cpu_init(void)  {  	unsigned int reg; diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c index c372a4373691..e6c1119c20ae 100644 --- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c @@ -67,6 +67,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {  	MX51_PAD_SD1_DATA1__SD1_DATA1,  	MX51_PAD_SD1_DATA2__SD1_DATA2,  	MX51_PAD_SD1_DATA3__SD1_DATA3, +	/* SD1 CD */ +	_MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP | +			PAD_CTL_PKE | PAD_CTL_SRE_FAST | +			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),  };  #define GPIO_LED1	IMX_GPIO_NR(3, 30) diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c index 51a67fc7f0ef..d0c7075937cf 100644 --- a/arch/arm/mach-mx5/mx51_efika.c +++ b/arch/arm/mach-mx5/mx51_efika.c @@ -42,7 +42,6 @@  #include <asm/mach-types.h>  #include <asm/mach/arch.h>  #include <asm/mach/time.h> -#include <asm/mach-types.h>  #include "devices-imx51.h"  #include "devices.h" @@ -572,8 +571,10 @@ static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = {  static struct mc13xxx_platform_data mx51_efika_mc13892_data = {  	.flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR, -	.num_regulators = ARRAY_SIZE(mx51_efika_regulators), -	.regulators = mx51_efika_regulators, +	.regulators = { +		.num_regulators = ARRAY_SIZE(mx51_efika_regulators), +		.regulators = mx51_efika_regulators, +	},  };  static struct spi_board_info mx51_efika_spi_board_info[] __initdata = { diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c new file mode 100644 index 000000000000..76ae8dc33e00 --- /dev/null +++ b/arch/arm/mach-mx5/system.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include <linux/platform_device.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include "crm_regs.h" + +/* set cpu low power mode before WFI instruction. This function is called +  * mx5 because it can be used for mx50, mx51, and mx53.*/ +void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) +{ +	u32 plat_lpc, arm_srpgcr, ccm_clpcr; +	u32 empgc0, empgc1; +	int stop_mode = 0; + +	/* always allow platform to issue a deep sleep mode request */ +	plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) & +	    ~(MXC_CORTEXA8_PLAT_LPC_DSM); +	ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); +	arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); +	empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); +	empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); + +	switch (mode) { +	case WAIT_CLOCKED: +		break; +	case WAIT_UNCLOCKED: +		ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET; +		break; +	case WAIT_UNCLOCKED_POWER_OFF: +	case STOP_POWER_OFF: +		plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM +			    | MXC_CORTEXA8_PLAT_LPC_DBG_DSM; +		if (mode == WAIT_UNCLOCKED_POWER_OFF) { +			ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET; +			ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY; +			ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS; +			stop_mode = 0; +		} else { +			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; +			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET; +			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY; +			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS; +			stop_mode = 1; +		} +		arm_srpgcr |= MXC_SRPGCR_PCR; + +		if (tzic_enable_wake(1) != 0) +			return; +		break; +	case STOP_POWER_ON: +		ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; +		break; +	default: +		printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode); +		return; +	} + +	__raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); +	__raw_writel(ccm_clpcr, MXC_CCM_CLPCR); +	__raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); + +	/* Enable NEON SRPG for all but MX50TO1.0. */ +	if (mx50_revision() != IMX_CHIP_REVISION_1_0) +		__raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); + +	if (stop_mode) { +		empgc0 |= MXC_SRPGCR_PCR; +		empgc1 |= MXC_SRPGCR_PCR; + +		__raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); +		__raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); +	} +} diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 4f6f174af6c8..4522fbb235d5 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -22,6 +22,7 @@ config MACH_MX23EVK  	select SOC_IMX23  	select MXS_HAVE_AMBA_DUART  	select MXS_HAVE_PLATFORM_AUART +	select MXS_HAVE_PLATFORM_MXS_MMC  	select MXS_HAVE_PLATFORM_MXSFB  	default y  	help @@ -35,6 +36,7 @@ config MACH_MX28EVK  	select MXS_HAVE_PLATFORM_AUART  	select MXS_HAVE_PLATFORM_FEC  	select MXS_HAVE_PLATFORM_FLEXCAN +	select MXS_HAVE_PLATFORM_MXS_MMC  	select MXS_HAVE_PLATFORM_MXSFB  	select MXS_OCOTP  	default y diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index d133c7f30940..c3577ea789ac 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c @@ -521,6 +521,15 @@ static int clk_misc_init(void)  	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,  			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET); +	/* +	 * 480 MHz seems too high to be ssp clock source directly, +	 * so set frac to get a 288 MHz ref_io. +	 */ +	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); +	reg &= ~BM_CLKCTRL_FRAC_IOFRAC; +	reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC; +	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); +  	return 0;  } @@ -528,6 +537,12 @@ int __init mx23_clocks_init(void)  {  	clk_misc_init(); +	/* +	 * source ssp clock from ref_io than ref_xtal, +	 * as ref_xtal only provides 24 MHz as maximum. +	 */ +	clk_set_parent(&ssp_clk, &ref_io_clk); +  	clk_enable(&cpu_clk);  	clk_enable(&hbus_clk);  	clk_enable(&xbus_clk); diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 5e489a2b2023..1ad97fed1e94 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -618,6 +618,8 @@ static struct clk_lookup lookups[] = {  	_REGISTER_CLOCK("pll2", NULL, pll2_clk)  	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)  	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk) +	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk) +	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)  	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)  	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)  	_REGISTER_CLOCK(NULL, "usb0", usb0_clk) @@ -737,6 +739,15 @@ static int clk_misc_init(void)  	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;  	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET); +	/* +	 * 480 MHz seems too high to be ssp clock source directly, +	 * so set frac0 to get a 288 MHz ref_io0. +	 */ +	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); +	reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC; +	reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC; +	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); +  	return 0;  } @@ -744,6 +755,13 @@ int __init mx28_clocks_init(void)  {  	clk_misc_init(); +	/* +	 * source ssp clock from ref_io0 than ref_xtal, +	 * as ref_xtal only provides 24 MHz as maximum. +	 */ +	clk_set_parent(&ssp0_clk, &ref_io0_clk); +	clk_set_parent(&ssp1_clk, &ref_io0_clk); +  	clk_enable(&cpu_clk);  	clk_enable(&hbus_clk);  	clk_enable(&xbus_clk); diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h index c7e14f4e3669..c6f345febd39 100644 --- a/arch/arm/mach-mxs/devices-mx23.h +++ b/arch/arm/mach-mxs/devices-mx23.h @@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst;  #define mx23_add_auart0()		mx23_add_auart(0)  #define mx23_add_auart1()		mx23_add_auart(1) +extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst; +#define mx23_add_mxs_mmc(id, pdata) \ +	mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata) +  #define mx23_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)  struct platform_device *__init mx23_add_mxsfb( diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index 9d08555c4cf0..c473eddce8cf 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -37,6 +37,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;  extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;  #define mx28_add_mxs_i2c(id)		mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id]) +extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst; +#define mx28_add_mxs_mmc(id, pdata) \ +	mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata) +  #define mx28_add_mxs_pwm(id)		mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)  struct platform_device *__init mx28_add_mxsfb( diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig index 1451ad060d82..acf9eea124c0 100644 --- a/arch/arm/mach-mxs/devices/Kconfig +++ b/arch/arm/mach-mxs/devices/Kconfig @@ -15,6 +15,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN  config MXS_HAVE_PLATFORM_MXS_I2C  	bool +config MXS_HAVE_PLATFORM_MXS_MMC +	bool +  config MXS_HAVE_PLATFORM_MXS_PWM  	bool diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile index 0d9bea30b0a2..324f2824d38d 100644 --- a/arch/arm/mach-mxs/devices/Makefile +++ b/arch/arm/mach-mxs/devices/Makefile @@ -4,5 +4,6 @@ obj-y += platform-dma.o  obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o  obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o  obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o +obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o  obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o  obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c new file mode 100644 index 000000000000..382dacbeca21 --- /dev/null +++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include <linux/compiler.h> +#include <linux/err.h> +#include <linux/init.h> + +#include <mach/mx23.h> +#include <mach/mx28.h> +#include <mach/devices-common.h> + +#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid)			\ +	{								\ +		.id = _id,						\ +		.iobase = soc ## _SSP ## hwid ## _BASE_ADDR,		\ +		.dma = soc ## _DMA_SSP ## hwid,				\ +		.irq_err = soc ## _INT_SSP ## hwid ## _ERROR,		\ +		.irq_dma = soc ## _INT_SSP ## hwid ## _DMA,		\ +	} + +#define mxs_mxs_mmc_data_entry(soc, _id, hwid)				\ +	[_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid) + + +#ifdef CONFIG_SOC_IMX23 +const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = { +	mxs_mxs_mmc_data_entry(MX23, 0, 1), +	mxs_mxs_mmc_data_entry(MX23, 1, 2), +}; +#endif + +#ifdef CONFIG_SOC_IMX28 +const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { +	mxs_mxs_mmc_data_entry(MX28, 0, 0), +	mxs_mxs_mmc_data_entry(MX28, 1, 1), +}; +#endif + +struct platform_device *__init mxs_add_mxs_mmc( +		const struct mxs_mxs_mmc_data *data, +		const struct mxs_mmc_platform_data *pdata) +{ +	struct resource res[] = { +		{ +			.start	= data->iobase, +			.end	= data->iobase + SZ_8K - 1, +			.flags	= IORESOURCE_MEM, +		}, { +			.start	= data->dma, +			.end	= data->dma, +			.flags	= IORESOURCE_DMA, +		}, { +			.start	= data->irq_err, +			.end	= data->irq_err, +			.flags	= IORESOURCE_IRQ, +		}, { +			.start	= data->irq_dma, +			.end	= data->irq_dma, +			.flags	= IORESOURCE_IRQ, +		}, +	}; + +	return mxs_add_platform_device("mxs-mmc", data->id, +			res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); +} diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index 71f24484b044..c5137f14c364 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -73,6 +73,19 @@ struct mxs_i2c_data {  };  struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data); +/* mmc */ +#include <mach/mmc.h> +struct mxs_mxs_mmc_data { +	int id; +	resource_size_t iobase; +	resource_size_t dma; +	resource_size_t irq_err; +	resource_size_t irq_dma; +}; +struct platform_device *__init mxs_add_mxs_mmc( +		const struct mxs_mxs_mmc_data *data, +		const struct mxs_mmc_platform_data *pdata); +  /* pwm */  struct platform_device *__init mxs_add_mxs_pwm(  		resource_size_t iobase, int id); diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c index a66994f0518f..214e5b641bbc 100644 --- a/arch/arm/mach-mxs/mach-mx23evk.c +++ b/arch/arm/mach-mxs/mach-mx23evk.c @@ -28,6 +28,8 @@  #define MX23EVK_LCD_ENABLE	MXS_GPIO_NR(1, 18)  #define MX23EVK_BL_ENABLE	MXS_GPIO_NR(1, 28) +#define MX23EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(1, 30) +#define MX23EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(1, 29)  static const iomux_cfg_t mx23evk_pads[] __initconst = {  	/* duart */ @@ -73,6 +75,36 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = {  	MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,  	/* backlight control */  	MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL, + +	/* mmc */ +	MX23_PAD_SSP1_DATA0__SSP1_DATA0 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_SSP1_DATA1__SSP1_DATA1 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_SSP1_DATA2__SSP1_DATA2 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_SSP1_DATA3__SSP1_DATA3 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_GPMI_D08__SSP1_DATA4 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_GPMI_D09__SSP1_DATA5 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_GPMI_D10__SSP1_DATA6 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_GPMI_D11__SSP1_DATA7 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_SSP1_CMD__SSP1_CMD | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX23_PAD_SSP1_DETECT__SSP1_DETECT | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	MX23_PAD_SSP1_SCK__SSP1_SCK | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* write protect */ +	MX23_PAD_PWM4__GPIO_1_30 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* slot power enable */ +	MX23_PAD_PWM3__GPIO_1_29 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),  };  /* mxsfb (lcdif) */ @@ -101,6 +133,11 @@ static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = {  	.ld_intf_width	= STMLCDIF_24BIT,  }; +static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = { +	.wp_gpio = MX23EVK_MMC0_WRITE_PROTECT, +	.flags = SLOTF_8_BIT_CAPABLE, +}; +  static void __init mx23evk_init(void)  {  	int ret; @@ -110,6 +147,13 @@ static void __init mx23evk_init(void)  	mx23_add_duart();  	mx23_add_auart0(); +	/* power on mmc slot by writing 0 to the gpio */ +	ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT, +			       "mmc0-slot-power"); +	if (ret) +		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); +	mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata); +  	ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");  	if (ret)  		pr_warn("failed to request gpio lcd-enable: %d\n", ret); diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index 08002d02267a..bb329b9a2608 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -34,6 +34,11 @@  #define MX28EVK_LCD_ENABLE	MXS_GPIO_NR(3, 30)  #define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13) +#define MX28EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(2, 12) +#define MX28EVK_MMC1_WRITE_PROTECT	MXS_GPIO_NR(0, 28) +#define MX28EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(3, 28) +#define MX28EVK_MMC1_SLOT_POWER		MXS_GPIO_NR(3, 29) +  static const iomux_cfg_t mx28evk_pads[] __initconst = {  	/* duart */  	MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL, @@ -115,6 +120,65 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {  	MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,  	/* backlight control */  	MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL, +	/* mmc0 */ +	MX28_PAD_SSP0_DATA0__SSP0_D0 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA1__SSP0_D1 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA2__SSP0_D2 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA3__SSP0_D3 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA4__SSP0_D4 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA5__SSP0_D5 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA6__SSP0_D6 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DATA7__SSP0_D7 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_CMD__SSP0_CMD | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	MX28_PAD_SSP0_SCK__SSP0_SCK | +		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* write protect */ +	MX28_PAD_SSP1_SCK__GPIO_2_12 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* slot power enable */ +	MX28_PAD_PWM3__GPIO_3_28 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + +	/* mmc1 */ +	MX28_PAD_GPMI_D00__SSP1_D0 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D01__SSP1_D1 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D02__SSP1_D2 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D03__SSP1_D3 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D04__SSP1_D4 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D05__SSP1_D5 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D06__SSP1_D6 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_D07__SSP1_D7 | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_RDY1__SSP1_CMD | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), +	MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT | +		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	MX28_PAD_GPMI_WRN__SSP1_SCK | +		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* write protect */ +	MX28_PAD_GPMI_RESETN__GPIO_0_28 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), +	/* slot power enable */ +	MX28_PAD_PWM4__GPIO_3_29 | +		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),  };  /* fec */ @@ -258,6 +322,18 @@ static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = {  	.ld_intf_width	= STMLCDIF_24BIT,  }; +static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = { +	{ +		/* mmc0 */ +		.wp_gpio = MX28EVK_MMC0_WRITE_PROTECT, +		.flags = SLOTF_8_BIT_CAPABLE, +	}, { +		/* mmc1 */ +		.wp_gpio = MX28EVK_MMC1_WRITE_PROTECT, +		.flags = SLOTF_8_BIT_CAPABLE, +	}, +}; +  static void __init mx28evk_init(void)  {  	int ret; @@ -297,6 +373,19 @@ static void __init mx28evk_init(void)  		gpio_set_value(MX28EVK_BL_ENABLE, 1);  	mx28_add_mxsfb(&mx28evk_mxsfb_pdata); + +	/* power on mmc slot by writing 0 to the gpio */ +	ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT, +			       "mmc0-slot-power"); +	if (ret) +		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); +	mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); + +	ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT, +			       "mmc1-slot-power"); +	if (ret) +		pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret); +	mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);  }  static void __init mx28evk_timer_init(void) diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c index fa0b154da67b..0fcff47009cf 100644 --- a/arch/arm/mach-mxs/module-tx28.c +++ b/arch/arm/mach-mxs/module-tx28.c @@ -45,7 +45,7 @@ static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {  };  #define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3) -static const iomux_cfg_t tx28_fec_pads[] __initconst = { +static const iomux_cfg_t tx28_fec0_pads[] __initconst = {  	MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,  	MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,  	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE, @@ -57,7 +57,20 @@ static const iomux_cfg_t tx28_fec_pads[] __initconst = {  	MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,  }; -static const struct fec_platform_data tx28_fec_data __initconst = { +static const iomux_cfg_t tx28_fec1_pads[] __initconst = { +	MX28_PAD_ENET0_RXD2__ENET1_RXD0, +	MX28_PAD_ENET0_RXD3__ENET1_RXD1, +	MX28_PAD_ENET0_TXD2__ENET1_TXD0, +	MX28_PAD_ENET0_TXD3__ENET1_TXD1, +	MX28_PAD_ENET0_COL__ENET1_TX_EN, +	MX28_PAD_ENET0_CRS__ENET1_RX_EN, +}; + +static struct fec_platform_data tx28_fec0_data = { +	.phy = PHY_INTERFACE_MODE_RMII, +}; + +static struct fec_platform_data tx28_fec1_data = {  	.phy = PHY_INTERFACE_MODE_RMII,  }; @@ -108,15 +121,15 @@ int __init tx28_add_fec0(void)  	pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);  	gpio_set_value(TX28_FEC_PHY_RESET, 1); -	ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads, -			ARRAY_SIZE(tx28_fec_pads)); +	ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads, +			ARRAY_SIZE(tx28_fec0_pads));  	if (ret) {  		pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",  				__func__, ret);  		goto free_gpios;  	} -	pr_debug("%s: Registering FEC device\n", __func__); -	mx28_add_fec(0, &tx28_fec_data); +	pr_debug("%s: Registering FEC0 device\n", __func__); +	mx28_add_fec(0, &tx28_fec0_data);  	return 0;  free_gpios: @@ -129,3 +142,19 @@ free_gpios:  	return ret;  } + +int __init tx28_add_fec1(void) +{ +	int ret; + +	ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads, +			ARRAY_SIZE(tx28_fec1_pads)); +	if (ret) { +		pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n", +				__func__, ret); +		return ret; +	} +	pr_debug("%s: Registering FEC1 device\n", __func__); +	mx28_add_fec(1, &tx28_fec1_data); +	return 0; +} diff --git a/arch/arm/mach-mxs/module-tx28.h b/arch/arm/mach-mxs/module-tx28.h index df9e1b6e81bf..8ed425457d30 100644 --- a/arch/arm/mach-mxs/module-tx28.h +++ b/arch/arm/mach-mxs/module-tx28.h @@ -7,3 +7,4 @@   * Free Software Foundation.   */  int __init tx28_add_fec0(void); +int __init tx28_add_fec1(void); diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c index 6561c9df5f0d..ccc789e21daa 100644 --- a/arch/arm/plat-mxc/devices/platform-fec.c +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -53,7 +53,7 @@ struct platform_device *__init imx_add_fec(  	struct resource res[] = {  		{  			.start = data->iobase, -			.end = data->iobase + SZ_4K, +			.end = data->iobase + SZ_4K - 1,  			.flags = IORESOURCE_MEM,  		}, {  			.start = data->irq, diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c index 10653cc8d1fa..805336fdc252 100644 --- a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c +++ b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c @@ -27,7 +27,7 @@ struct platform_device *__init imx_add_imxdi_rtc(  	struct resource res[] = {  		{  			.start = data->iobase, -			.end = data->iobase + SZ_16K, +			.end = data->iobase + SZ_16K - 1,  			.flags = IORESOURCE_MEM,  		}, {  			.start = data->irq, diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h index 5cd6466964af..6fda788ed0e9 100644 --- a/arch/arm/plat-mxc/include/mach/audmux.h +++ b/arch/arm/plat-mxc/include/mach/audmux.h @@ -15,6 +15,14 @@  #define MX31_AUDMUX_PORT5_SSI_PINS_5	4  #define MX31_AUDMUX_PORT6_SSI_PINS_6	5 +#define MX51_AUDMUX_PORT1_SSI0		0 +#define MX51_AUDMUX_PORT2_SSI1		1 +#define MX51_AUDMUX_PORT3		2 +#define MX51_AUDMUX_PORT4		3 +#define MX51_AUDMUX_PORT5		4 +#define MX51_AUDMUX_PORT6		5 +#define MX51_AUDMUX_PORT7		6 +  /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */  #define MXC_AUDMUX_V1_PCR_INMMASK(x)	((x) & 0xff)  #define MXC_AUDMUX_V1_PCR_INMEN		(1 << 8) @@ -28,7 +36,7 @@  #define MXC_AUDMUX_V1_PCR_TCLKDIR	(1 << 30)  #define MXC_AUDMUX_V1_PCR_TFSDIR	(1 << 31) -/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */ +/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */  #define MXC_AUDMUX_V2_PTCR_TFSDIR	(1 << 31)  #define MXC_AUDMUX_V2_PTCR_TFSEL(x)	(((x) & 0xf) << 27)  #define MXC_AUDMUX_V2_PTCR_TCLKDIR	(1 << 26) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h index c4f116d214f2..7a9b20abda09 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h @@ -90,12 +90,12 @@  #define PC31_PF_SSI3_CLK	(GPIO_PORTC | GPIO_PF | GPIO_IN | 31)  #define PD17_PF_I2C_DATA	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)  #define PD18_PF_I2C_CLK		(GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) -#define PD19_PF_CSPI2_SS2	(GPIO_PORTD | GPIO_PF | 19) -#define PD20_PF_CSPI2_SS1	(GPIO_PORTD | GPIO_PF | 20) -#define PD21_PF_CSPI2_SS0	(GPIO_PORTD | GPIO_PF | 21) -#define PD22_PF_CSPI2_SCLK	(GPIO_PORTD | GPIO_PF | 22) -#define PD23_PF_CSPI2_MISO	(GPIO_PORTD | GPIO_PF | 23) -#define PD24_PF_CSPI2_MOSI	(GPIO_PORTD | GPIO_PF | 24) +#define PD19_PF_CSPI2_SS2	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 19) +#define PD20_PF_CSPI2_SS1	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 20) +#define PD21_PF_CSPI2_SS0	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 21) +#define PD22_PF_CSPI2_SCLK	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 22) +#define PD23_PF_CSPI2_MISO	(GPIO_PORTD | GPIO_PF | GPIO_IN | 23) +#define PD24_PF_CSPI2_MOSI	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)  #define PD25_PF_CSPI1_RDY	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)  #define PD26_PF_CSPI1_SS2	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)  #define PD27_PF_CSPI1_SS1	(GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/plat-mxc/include/mach/mx50.h index aaec2a6e7b3a..5f2da75a47f4 100644 --- a/arch/arm/plat-mxc/include/mach/mx50.h +++ b/arch/arm/plat-mxc/include/mach/mx50.h @@ -282,4 +282,8 @@  #define MX50_INT_APBHDMA_CHAN6	116  #define MX50_INT_APBHDMA_CHAN7	117 +#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) +extern int mx50_revision(void); +#endif +  #endif /* ifndef __MACH_MX50_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 1eb339e6c857..dede19a766ff 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -347,6 +347,7 @@  #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)  extern int mx51_revision(void); +extern void mx51_display_revision(void);  #endif  /* tape-out 1 defines */ diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index 7e072637eefa..1aea818d9d31 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -51,6 +51,20 @@  #define IMX_CHIP_REVISION_3_3		0x33  #define IMX_CHIP_REVISION_UNKNOWN	0xff +#define IMX_CHIP_REVISION_1_0_STRING		"1.0" +#define IMX_CHIP_REVISION_1_1_STRING		"1.1" +#define IMX_CHIP_REVISION_1_2_STRING		"1.2" +#define IMX_CHIP_REVISION_1_3_STRING		"1.3" +#define IMX_CHIP_REVISION_2_0_STRING		"2.0" +#define IMX_CHIP_REVISION_2_1_STRING		"2.1" +#define IMX_CHIP_REVISION_2_2_STRING		"2.2" +#define IMX_CHIP_REVISION_2_3_STRING		"2.3" +#define IMX_CHIP_REVISION_3_0_STRING		"3.0" +#define IMX_CHIP_REVISION_3_1_STRING		"3.1" +#define IMX_CHIP_REVISION_3_2_STRING		"3.2" +#define IMX_CHIP_REVISION_3_3_STRING		"3.3" +#define IMX_CHIP_REVISION_UNKNOWN_STRING	"unknown" +  #ifndef __ASSEMBLY__  extern unsigned int __mxc_cpu_type;  #endif @@ -181,6 +195,15 @@ struct cpu_op {  	u32 cpu_rate;  }; +int tzic_enable_wake(int is_idle); +enum mxc_cpu_pwr_mode { +	WAIT_CLOCKED,		/* wfi only */ +	WAIT_UNCLOCKED,		/* WAIT */ +	WAIT_UNCLOCKED_POWER_OFF,	/* WAIT + SRPG */ +	STOP_POWER_ON,		/* just STOP */ +	STOP_POWER_OFF,		/* STOP + SRPG */ +}; +  extern struct cpu_op *(*get_cpu_op)(int *op);  #endif diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index 95be51bfe9a9..0417da9f710d 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -20,6 +20,8 @@  #include <mach/hardware.h>  #include <mach/common.h> +extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); +  static inline void arch_idle(void)  {  #ifdef CONFIG_ARCH_MXC91231 @@ -54,7 +56,9 @@ static inline void arch_idle(void)  			"orr %0, %0, #0x00000004\n"  			"mcr p15, 0, %0, c1, c0, 0\n"  			: "=r" (reg)); -	} else +	} else if (cpu_is_mx51()) +		mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); +	else  		cpu_do_idle();  } diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 9f0c2610595e..2237ff8b434f 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -27,6 +27,7 @@  #include <linux/clk.h>  #include <mach/hardware.h> +#include <asm/sched_clock.h>  #include <asm/mach/time.h>  #include <mach/common.h> @@ -105,6 +106,11 @@ static void gpt_irq_acknowledge(void)  		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);  } +static cycle_t dummy_get_cycles(struct clocksource *cs) +{ +	return 0; +} +  static cycle_t mx1_2_get_cycles(struct clocksource *cs)  {  	return __raw_readl(timer_base + MX1_2_TCN); @@ -118,18 +124,35 @@ static cycle_t v2_get_cycles(struct clocksource *cs)  static struct clocksource clocksource_mxc = {  	.name 		= "mxc_timer1",  	.rating		= 200, -	.read		= mx1_2_get_cycles, +	.read		= dummy_get_cycles,  	.mask		= CLOCKSOURCE_MASK(32),  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,  }; +static DEFINE_CLOCK_DATA(cd); +unsigned long long notrace sched_clock(void) +{ +	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + +	return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace mxc_update_sched_clock(void) +{ +	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); +	update_sched_clock(&cd, cyc, (u32)~0); +} +  static int __init mxc_clocksource_init(struct clk *timer_clk)  {  	unsigned int c = clk_get_rate(timer_clk);  	if (timer_is_v2())  		clocksource_mxc.read = v2_get_cycles; +	else +		clocksource_mxc.read = mx1_2_get_cycles; +	init_sched_clock(&cd, mxc_update_sched_clock, 32, c);  	clocksource_register_hz(&clocksource_mxc, c);  	return 0; | 
