diff options
Diffstat (limited to 'arch/arm/mach-mx5')
24 files changed, 1671 insertions, 237 deletions
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 3ec910a7a182..de4fa992fc3e 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -1,20 +1,47 @@ if ARCH_MX5 +# ARCH_MX51 and ARCH_MX50 are left for compatibility + +config ARCH_MX50 + bool config ARCH_MX51 bool - default y + +config ARCH_MX53 + bool + +config SOC_IMX50 + bool select MXC_TZIC select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 select ARCH_HAS_CPUFREQ + select ARCH_MX50 + +config SOC_IMX51 + bool + select MXC_TZIC + select ARCH_MXC_IOMUX_V3 + select ARCH_MXC_AUDMUX_V2 + select ARCH_HAS_CPUFREQ + select ARCH_MX51 + +config SOC_IMX53 + bool + select MXC_TZIC + select ARCH_MXC_IOMUX_V3 + select ARCH_MX53 comment "MX5 platforms:" config MACH_MX51_BABBAGE bool "Support MX51 BABBAGE platforms" + select SOC_IMX51 + select IMX_HAVE_PLATFORM_IMX2_WDT select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART - select IMX_HAVE_PLATFORM_ESDHC + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_SPI_IMX help Include support for MX51 Babbage platform, also known as MX51EVK in u-boot. This includes specific configurations for the board and its @@ -22,7 +49,10 @@ config MACH_MX51_BABBAGE config MACH_MX51_3DS bool "Support MX51PDK (3DS)" + select SOC_IMX51 + select IMX_HAVE_PLATFORM_IMX_KEYPAD select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX select IMX_HAVE_PLATFORM_SPI_IMX select MXC_DEBUG_BOARD help @@ -31,6 +61,7 @@ config MACH_MX51_3DS config MACH_EUKREA_CPUIMX51 bool "Support Eukrea CPUIMX51 module" + select SOC_IMX51 select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_NAND @@ -47,7 +78,8 @@ choice config MACH_EUKREA_MBIMX51_BASEBOARD prompt "Eukrea MBIMX51 development board" bool - select IMX_HAVE_PLATFORM_ESDHC + select IMX_HAVE_PLATFORM_IMX_KEYPAD + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX help This adds board specific devices that can be found on Eukrea's MBIMX51 evaluation board. @@ -56,6 +88,7 @@ endchoice config MACH_EUKREA_CPUIMX51SD bool "Support Eukrea CPUIMX51SD module" + select SOC_IMX51 select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_SPI_IMX select IMX_HAVE_PLATFORM_IMX_UART @@ -72,7 +105,7 @@ choice config MACH_EUKREA_MBIMXSD51_BASEBOARD prompt "Eukrea MBIMXSD development board" bool - select IMX_HAVE_PLATFORM_ESDHC + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX help This adds board specific devices that can be found on Eukrea's MBIMXSD evaluation board. @@ -81,9 +114,51 @@ endchoice config MACH_MX51_EFIKAMX bool "Support MX51 Genesi Efika MX nettop" + select SOC_IMX51 select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_SPI_IMX help Include support for Genesi Efika MX nettop. This includes specific configurations for the board and its peripherals. +config MACH_MX53_EVK + bool "Support MX53 EVK platforms" + select SOC_IMX53 + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_SPI_IMX + help + Include support for MX53 EVK platform. This includes specific + configurations for the board and its peripherals. + +config MACH_MX53_SMD + bool "Support MX53 SMD platforms" + select SOC_IMX53 + select IMX_HAVE_PLATFORM_IMX_UART + help + Include support for MX53 SMD platform. This includes specific + configurations for the board and its peripherals. + +config MACH_MX53_LOCO + bool "Support MX53 LOCO platforms" + select SOC_IMX53 + select IMX_HAVE_PLATFORM_IMX_UART + help + Include support for MX53 LOCO platform. This includes specific + configurations for the board and its peripherals. + +config MACH_MX50_RDP + bool "Support MX50 reference design platform" + depends on BROKEN + select SOC_IMX50 + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_SPI_IMX + help + Include support for MX50 reference design platform (RDP) board. This + includes specific configurations for the board and its peripherals. + endif diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 462f177eddfe..0d43be98e51c 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -3,13 +3,18 @@ # # Object file lists. -obj-y := cpu.o mm.o clock-mx51.o devices.o +obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o +obj-$(CONFIG_SOC_IMX50) += mm-mx50.o obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o +obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o +obj-$(CONFIG_MACH_MX53_SMD) += board-mx53_smd.o +obj-$(CONFIG_MACH_MX53_LOCO) += board-mx53_loco.o obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o +obj-$(CONFIG_MACH_MX50_RDP) += board-mx50_rdp.o diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot index 9939a19d99a1..e928be1b6757 100644 --- a/arch/arm/mach-mx5/Makefile.boot +++ b/arch/arm/mach-mx5/Makefile.boot @@ -1,3 +1,9 @@ - zreladdr-y := 0x90008000 -params_phys-y := 0x90000100 -initrd_phys-y := 0x90800000 + zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000 +params_phys-$(CONFIG_ARCH_MX50) := 0x70000100 +initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000 + zreladdr-$(CONFIG_ARCH_MX51) := 0x90008000 +params_phys-$(CONFIG_ARCH_MX51) := 0x90000100 +initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000 + zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000 +params_phys-$(CONFIG_ARCH_MX53) := 0x70000100 +initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000 diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c index 6a9792fd0a76..f8652ef25f85 100644 --- a/arch/arm/mach-mx5/board-cpuimx51.c +++ b/arch/arm/mach-mx5/board-cpuimx51.c @@ -40,11 +40,11 @@ #include "devices-imx51.h" #include "devices.h" -#define CPUIMX51_USBH1_STP (0*32 + 27) -#define CPUIMX51_QUARTA_GPIO (2*32 + 28) -#define CPUIMX51_QUARTB_GPIO (2*32 + 25) -#define CPUIMX51_QUARTC_GPIO (2*32 + 26) -#define CPUIMX51_QUARTD_GPIO (2*32 + 27) +#define CPUIMX51_USBH1_STP IMX_GPIO_NR(1, 27) +#define CPUIMX51_QUARTA_GPIO IMX_GPIO_NR(3, 28) +#define CPUIMX51_QUARTB_GPIO IMX_GPIO_NR(3, 25) +#define CPUIMX51_QUARTC_GPIO IMX_GPIO_NR(3, 26) +#define CPUIMX51_QUARTD_GPIO IMX_GPIO_NR(3, 27) #define CPUIMX51_QUARTA_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO) #define CPUIMX51_QUARTB_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO) #define CPUIMX51_QUARTC_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO) @@ -113,7 +113,7 @@ static struct platform_device *devices[] __initdata = { #endif }; -static struct pad_desc eukrea_cpuimx51_pads[] = { +static iomux_v3_cfg_t eukrea_cpuimx51_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, MX51_PAD_UART1_TXD__UART1_TXD, @@ -121,15 +121,15 @@ static struct pad_desc eukrea_cpuimx51_pads[] = { MX51_PAD_UART1_CTS__UART1_CTS, /* I2C2 */ - MX51_PAD_GPIO_1_2__I2C2_SCL, - MX51_PAD_GPIO_1_3__I2C2_SDA, - MX51_PAD_NANDF_D10__GPIO_3_30, + MX51_PAD_GPIO1_2__I2C2_SCL, + MX51_PAD_GPIO1_3__I2C2_SDA, + MX51_PAD_NANDF_D10__GPIO3_30, /* QUART IRQ */ - MX51_PAD_NANDF_D15__GPIO_3_25, - MX51_PAD_NANDF_D14__GPIO_3_26, - MX51_PAD_NANDF_D13__GPIO_3_27, - MX51_PAD_NANDF_D12__GPIO_3_28, + MX51_PAD_NANDF_D15__GPIO3_25, + MX51_PAD_NANDF_D14__GPIO3_26, + MX51_PAD_NANDF_D13__GPIO3_27, + MX51_PAD_NANDF_D12__GPIO3_28, /* USB HOST1 */ MX51_PAD_USBH1_CLK__USBH1_CLK, @@ -178,6 +178,8 @@ static int initialize_otg_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* Set the PHY clock to 19.2MHz */ @@ -196,6 +198,8 @@ static int initialize_usbh1_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* The clock for the USBH1 ULPI port will come externally from the PHY. */ @@ -292,7 +296,7 @@ static struct sys_timer mxc_timer = { MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module") /* Maintainer: Eric Bénard <eric@eukrea.com> */ - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = MX51_PHYS_OFFSET + 0x100, .map_io = mx51_map_io, .init_irq = mx51_init_irq, .init_machine = eukrea_cpuimx51_init, diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c index 4b3a6119c5fb..ad931895d8b6 100644 --- a/arch/arm/mach-mx5/board-cpuimx51sd.c +++ b/arch/arm/mach-mx5/board-cpuimx51sd.c @@ -43,19 +43,19 @@ #include "devices-imx51.h" #include "devices.h" -#define USBH1_RST (1*32 + 28) -#define ETH_RST (1*32 + 31) -#define TSC2007_IRQGPIO (2*32 + 12) -#define CAN_IRQGPIO (0*32 + 1) -#define CAN_RST (3*32 + 15) -#define CAN_NCS (3*32 + 24) -#define CAN_RXOBF (0*32 + 4) -#define CAN_RX1BF (0*32 + 6) -#define CAN_TXORTS (0*32 + 7) -#define CAN_TX1RTS (0*32 + 8) -#define CAN_TX2RTS (0*32 + 9) -#define I2C_SCL (3*32 + 16) -#define I2C_SDA (3*32 + 17) +#define USBH1_RST IMX_GPIO_NR(2, 28) +#define ETH_RST IMX_GPIO_NR(2, 31) +#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 12) +#define CAN_IRQGPIO IMX_GPIO_NR(1, 1) +#define CAN_RST IMX_GPIO_NR(4, 15) +#define CAN_NCS IMX_GPIO_NR(4, 24) +#define CAN_RXOBF IMX_GPIO_NR(1, 4) +#define CAN_RX1BF IMX_GPIO_NR(1, 6) +#define CAN_TXORTS IMX_GPIO_NR(1, 7) +#define CAN_TX1RTS IMX_GPIO_NR(1, 8) +#define CAN_TX2RTS IMX_GPIO_NR(1, 9) +#define I2C_SCL IMX_GPIO_NR(4, 16) +#define I2C_SDA IMX_GPIO_NR(4, 17) /* USB_CTRL_1 */ #define MX51_USB_CTRL_1_OFFSET 0x10 @@ -65,10 +65,7 @@ #define MX51_USB_PLL_DIV_19_2_MHZ 0x01 #define MX51_USB_PLL_DIV_24_MHZ 0x02 -#define CPUIMX51SD_GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, \ - MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP) - -static struct pad_desc eukrea_cpuimx51sd_pads[] = { +static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, MX51_PAD_UART1_TXD__UART1_TXD, @@ -88,30 +85,33 @@ static struct pad_desc eukrea_cpuimx51sd_pads[] = { MX51_PAD_USBH1_DATA6__USBH1_DATA6, MX51_PAD_USBH1_DATA7__USBH1_DATA7, MX51_PAD_USBH1_STP__USBH1_STP, - MX51_PAD_EIM_CS3__GPIO_2_28, /* PHY nRESET */ + MX51_PAD_EIM_CS3__GPIO2_28, /* PHY nRESET */ /* FEC */ - MX51_PAD_EIM_DTACK__GPIO_2_31, /* PHY nRESET */ + MX51_PAD_EIM_DTACK__GPIO2_31, /* PHY nRESET */ /* HSI2C */ - MX51_PAD_I2C1_CLK__GPIO_4_16, - MX51_PAD_I2C1_DAT__GPIO_4_17, + MX51_PAD_I2C1_CLK__GPIO4_16, + MX51_PAD_I2C1_DAT__GPIO4_17, /* CAN */ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, MX51_PAD_CSPI1_MISO__ECSPI1_MISO, MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, - MX51_PAD_CSPI1_SS0__GPIO_4_24, /* nCS */ - MX51_PAD_CSI2_PIXCLK__GPIO_4_15, /* nReset */ - MX51_PAD_GPIO_1_1__GPIO_1_1, /* IRQ */ - MX51_PAD_GPIO_1_4__GPIO_1_4, /* Control signals */ - MX51_PAD_GPIO_1_6__GPIO_1_6, - MX51_PAD_GPIO_1_7__GPIO_1_7, - MX51_PAD_GPIO_1_8__GPIO_1_8, - MX51_PAD_GPIO_1_9__GPIO_1_9, + MX51_PAD_CSPI1_SS0__GPIO4_24, /* nCS */ + MX51_PAD_CSI2_PIXCLK__GPIO4_15, /* nReset */ + MX51_PAD_GPIO1_1__GPIO1_1, /* IRQ */ + MX51_PAD_GPIO1_4__GPIO1_4, /* Control signals */ + MX51_PAD_GPIO1_6__GPIO1_6, + MX51_PAD_GPIO1_7__GPIO1_7, + MX51_PAD_GPIO1_8__GPIO1_8, + MX51_PAD_GPIO1_9__GPIO1_9, /* Touchscreen */ - CPUIMX51SD_GPIO_3_12, /* IRQ */ + /* IRQ */ + _MX51_PAD_CSI1_D8__GPIO3_12 | 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), }; static const struct imxuart_platform_data uart_pdata __initconst = { @@ -157,6 +157,8 @@ static int initialize_otg_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* Set the PHY clock to 19.2MHz */ @@ -175,6 +177,8 @@ static int initialize_usbh1_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* The clock for the USBH1 ULPI port will come from the PHY. */ @@ -243,7 +247,7 @@ static struct spi_board_info cpuimx51sd_spi_device[] = { .mode = SPI_MODE_0, .chip_select = 0, .platform_data = &mcp251x_info, - .irq = gpio_to_irq(0 * 32 + 1) + .irq = gpio_to_irq(CAN_IRQGPIO) }, }; @@ -323,7 +327,7 @@ static struct sys_timer mxc_timer = { MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD") /* Maintainer: Eric Bénard <eric@eukrea.com> */ - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = MX51_PHYS_OFFSET + 0x100, .map_io = mx51_map_io, .init_irq = mx51_init_irq, .init_machine = eukrea_cpuimx51sd_init, diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c new file mode 100644 index 000000000000..fd32e4c450e8 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx50_rdp.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/fsl_devices.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/iomux-mx50.h> + +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "devices-mx50.h" + +static iomux_v3_cfg_t mx50_rdp_pads[] __initdata = { + /* SD1 */ + MX50_PAD_ECSPI2_SS0__GPIO_4_19, + MX50_PAD_EIM_CRE__GPIO_1_27, + MX50_PAD_SD1_CMD__SD1_CMD, + + MX50_PAD_SD1_CLK__SD1_CLK, + MX50_PAD_SD1_D0__SD1_D0, + MX50_PAD_SD1_D1__SD1_D1, + MX50_PAD_SD1_D2__SD1_D2, + MX50_PAD_SD1_D3__SD1_D3, + + /* SD2 */ + MX50_PAD_SD2_CD__GPIO_5_17, + MX50_PAD_SD2_WP__GPIO_5_16, + MX50_PAD_SD2_CMD__SD2_CMD, + MX50_PAD_SD2_CLK__SD2_CLK, + MX50_PAD_SD2_D0__SD2_D0, + MX50_PAD_SD2_D1__SD2_D1, + MX50_PAD_SD2_D2__SD2_D2, + MX50_PAD_SD2_D3__SD2_D3, + MX50_PAD_SD2_D4__SD2_D4, + MX50_PAD_SD2_D5__SD2_D5, + MX50_PAD_SD2_D6__SD2_D6, + MX50_PAD_SD2_D7__SD2_D7, + + /* SD3 */ + MX50_PAD_SD3_CMD__SD3_CMD, + MX50_PAD_SD3_CLK__SD3_CLK, + MX50_PAD_SD3_D0__SD3_D0, + MX50_PAD_SD3_D1__SD3_D1, + MX50_PAD_SD3_D2__SD3_D2, + MX50_PAD_SD3_D3__SD3_D3, + MX50_PAD_SD3_D4__SD3_D4, + MX50_PAD_SD3_D5__SD3_D5, + MX50_PAD_SD3_D6__SD3_D6, + MX50_PAD_SD3_D7__SD3_D7, + + /* PWR_INT */ + MX50_PAD_ECSPI2_MISO__GPIO_4_18, + + /* UART pad setting */ + MX50_PAD_UART1_TXD__UART1_TXD, + MX50_PAD_UART1_RXD__UART1_RXD, + MX50_PAD_UART1_RTS__UART1_RTS, + MX50_PAD_UART2_TXD__UART2_TXD, + MX50_PAD_UART2_RXD__UART2_RXD, + MX50_PAD_UART2_CTS__UART2_CTS, + MX50_PAD_UART2_RTS__UART2_RTS, + + MX50_PAD_I2C1_SCL__I2C1_SCL, + MX50_PAD_I2C1_SDA__I2C1_SDA, + MX50_PAD_I2C2_SCL__I2C2_SCL, + MX50_PAD_I2C2_SDA__I2C2_SDA, + + MX50_PAD_EPITO__USBH1_PWR, + /* Need to comment below line if + * one needs to debug owire. + */ + MX50_PAD_OWIRE__USBH1_OC, + /* using gpio to control otg pwr */ + MX50_PAD_PWM2__GPIO_6_25, + MX50_PAD_I2C3_SCL__USBOTG_OC, + + MX50_PAD_SSI_RXC__FEC_MDIO, + MX50_PAD_SSI_RXC__FEC_MDIO, + MX50_PAD_DISP_D0__FEC_TXCLK, + MX50_PAD_DISP_D1__FEC_RX_ER, + MX50_PAD_DISP_D2__FEC_RX_DV, + MX50_PAD_DISP_D3__FEC_RXD1, + MX50_PAD_DISP_D4__FEC_RXD0, + MX50_PAD_DISP_D5__FEC_TX_EN, + MX50_PAD_DISP_D6__FEC_TXD1, + MX50_PAD_DISP_D7__FEC_TXD0, + MX50_PAD_SSI_RXFS__FEC_MDC, + MX50_PAD_I2C3_SDA__GPIO_6_23, + MX50_PAD_ECSPI1_SCLK__GPIO_4_12, + + MX50_PAD_CSPI_SS0__CSPI_SS0, + MX50_PAD_ECSPI1_MOSI__CSPI_SS1, + MX50_PAD_CSPI_MOSI__CSPI_MOSI, + MX50_PAD_CSPI_MISO__CSPI_MISO, + + /* SGTL500_OSC_EN */ + MX50_PAD_UART1_CTS__GPIO_6_8, + + /* SGTL_AMP_SHDN */ + MX50_PAD_UART3_RXD__GPIO_6_15, + + /* Keypad */ + MX50_PAD_KEY_COL0__KEY_COL0, + MX50_PAD_KEY_ROW0__KEY_ROW0, + MX50_PAD_KEY_COL1__KEY_COL1, + MX50_PAD_KEY_ROW1__KEY_ROW1, + MX50_PAD_KEY_COL2__KEY_COL2, + MX50_PAD_KEY_ROW2__KEY_ROW2, + MX50_PAD_KEY_COL3__KEY_COL3, + MX50_PAD_KEY_ROW3__KEY_ROW3, + MX50_PAD_EIM_DA0__KEY_COL4, + MX50_PAD_EIM_DA1__KEY_ROW4, + MX50_PAD_EIM_DA2__KEY_COL5, + MX50_PAD_EIM_DA3__KEY_ROW5, + MX50_PAD_EIM_DA4__KEY_COL6, + MX50_PAD_EIM_DA5__KEY_ROW6, + MX50_PAD_EIM_DA6__KEY_COL7, + MX50_PAD_EIM_DA7__KEY_ROW7, + /*EIM pads */ + MX50_PAD_EIM_DA8__GPIO_1_8, + MX50_PAD_EIM_DA9__GPIO_1_9, + MX50_PAD_EIM_DA10__GPIO_1_10, + MX50_PAD_EIM_DA11__GPIO_1_11, + MX50_PAD_EIM_DA12__GPIO_1_12, + MX50_PAD_EIM_DA13__GPIO_1_13, + MX50_PAD_EIM_DA14__GPIO_1_14, + MX50_PAD_EIM_DA15__GPIO_1_15, + MX50_PAD_EIM_CS2__GPIO_1_16, + MX50_PAD_EIM_CS1__GPIO_1_17, + MX50_PAD_EIM_CS0__GPIO_1_18, + MX50_PAD_EIM_EB0__GPIO_1_19, + MX50_PAD_EIM_EB1__GPIO_1_20, + MX50_PAD_EIM_WAIT__GPIO_1_21, + MX50_PAD_EIM_BCLK__GPIO_1_22, + MX50_PAD_EIM_RDY__GPIO_1_23, + MX50_PAD_EIM_OE__GPIO_1_24, +}; + +/* Serial ports */ +static const struct imxuart_platform_data uart_pdata __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +/* + * Board specific initialization. + */ +static void __init mx50_rdp_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads, + ARRAY_SIZE(mx50_rdp_pads)); + + imx50_add_imx_uart(0, &uart_pdata); + imx50_add_imx_uart(1, &uart_pdata); +} + +static void __init mx50_rdp_timer_init(void) +{ + mx50_clocks_init(32768, 24000000, 22579200); +} + +static struct sys_timer mx50_rdp_timer = { + .init = mx50_rdp_timer_init, +}; + +MACHINE_START(MX50_RDP, "Freescale MX50 Reference Design Platform") + .map_io = mx50_map_io, + .init_irq = mx50_init_irq, + .init_machine = mx50_rdp_board_init, + .timer = &mx50_rdp_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c index 79ce8dcf3cda..49d644842379 100644 --- a/arch/arm/mach-mx5/board-mx51_3ds.c +++ b/arch/arm/mach-mx5/board-mx51_3ds.c @@ -12,7 +12,6 @@ #include <linux/irq.h> #include <linux/platform_device.h> -#include <linux/input/matrix_keypad.h> #include <linux/spi/spi.h> #include <asm/mach-types.h> @@ -30,7 +29,7 @@ #define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6) #define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28) -static struct pad_desc mx51_3ds_pads[] = { +static iomux_v3_cfg_t mx51_3ds_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, MX51_PAD_UART1_TXD__UART1_TXD, @@ -50,7 +49,7 @@ static struct pad_desc mx51_3ds_pads[] = { MX51_PAD_EIM_D27__UART3_RTS, /* CPLD PARENT IRQ PIN */ - MX51_PAD_GPIO_1_6__GPIO_1_6, + MX51_PAD_GPIO1_6__GPIO1_6, /* KPP */ MX51_PAD_KEY_ROW0__KEY_ROW0, @@ -68,7 +67,7 @@ static struct pad_desc mx51_3ds_pads[] = { MX51_PAD_NANDF_RB2__ECSPI2_SCLK, MX51_PAD_NANDF_RB3__ECSPI2_MISO, MX51_PAD_NANDF_D15__ECSPI2_MOSI, - MX51_PAD_NANDF_D12__GPIO_3_28, + MX51_PAD_NANDF_D12__GPIO3_28, }; /* Serial ports */ @@ -120,14 +119,14 @@ static int mx51_3ds_board_keymap[] = { KEY(3, 5, KEY_BACK) }; -static struct matrix_keymap_data mx51_3ds_map_data = { +static const struct matrix_keymap_data mx51_3ds_map_data __initconst = { .keymap = mx51_3ds_board_keymap, .keymap_size = ARRAY_SIZE(mx51_3ds_board_keymap), }; static void mxc_init_keypad(void) { - mxc_register_device(&mxc_keypad_device, &mx51_3ds_map_data); + imx51_add_imx_keypad(&mx51_3ds_map_data); } #else static inline void mxc_init_keypad(void) @@ -172,6 +171,7 @@ static void __init mxc_board_init(void) printk(KERN_WARNING "Init of the debugboard failed, all " "devices on the board are unusable.\n"); + imx51_add_sdhci_esdhc_imx(0, NULL); mxc_init_keypad(); } @@ -186,7 +186,7 @@ static struct sys_timer mxc_timer = { MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board") /* Maintainer: Freescale Semiconductor, Inc. */ - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = MX51_PHYS_OFFSET + 0x100, .map_io = mx51_map_io, .init_irq = mx51_init_irq, .init_machine = mxc_board_init, diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index acbe30df2e69..1d231e84107c 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -20,6 +20,8 @@ #include <linux/fec.h> #include <linux/gpio_keys.h> #include <linux/input.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> #include <mach/common.h> #include <mach/hardware.h> @@ -36,11 +38,13 @@ #include "devices.h" #include "cpu_op-mx51.h" -#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */ -#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */ -#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */ -#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */ -#define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */ +#define BABBAGE_USB_HUB_RESET IMX_GPIO_NR(1, 7) +#define BABBAGE_USBH1_STP IMX_GPIO_NR(1, 27) +#define BABBAGE_PHY_RESET IMX_GPIO_NR(2, 5) +#define BABBAGE_FEC_PHY_RESET IMX_GPIO_NR(2, 14) +#define BABBAGE_POWER_KEY IMX_GPIO_NR(2, 21) +#define BABBAGE_ECSPI1_CS0 IMX_GPIO_NR(4, 24) +#define BABBAGE_ECSPI1_CS1 IMX_GPIO_NR(4, 25) /* USB_CTRL_1 */ #define MX51_USB_CTRL_1_OFFSET 0x10 @@ -65,7 +69,7 @@ static const struct gpio_keys_platform_data imx_button_data __initconst = { .nbuttons = ARRAY_SIZE(babbage_buttons), }; -static struct pad_desc mx51babbage_pads[] = { +static iomux_v3_cfg_t mx51babbage_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, MX51_PAD_UART1_TXD__UART1_TXD, @@ -91,8 +95,8 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_KEY_COL5__I2C2_SDA, /* HSI2C */ - MX51_PAD_I2C1_CLK__HSI2C_CLK, - MX51_PAD_I2C1_DAT__HSI2C_DAT, + MX51_PAD_I2C1_CLK__I2C1_CLK, + MX51_PAD_I2C1_DAT__I2C1_DAT, /* USB HOST1 */ MX51_PAD_USBH1_CLK__USBH1_CLK, @@ -108,29 +112,29 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_USBH1_DATA7__USBH1_DATA7, /* USB HUB reset line*/ - MX51_PAD_GPIO_1_7__GPIO_1_7, + MX51_PAD_GPIO1_7__GPIO1_7, /* FEC */ MX51_PAD_EIM_EB2__FEC_MDIO, - MX51_PAD_EIM_EB3__FEC_RDAT1, - MX51_PAD_EIM_CS2__FEC_RDAT2, - MX51_PAD_EIM_CS3__FEC_RDAT3, + MX51_PAD_EIM_EB3__FEC_RDATA1, + MX51_PAD_EIM_CS2__FEC_RDATA2, + MX51_PAD_EIM_CS3__FEC_RDATA3, MX51_PAD_EIM_CS4__FEC_RX_ER, MX51_PAD_EIM_CS5__FEC_CRS, MX51_PAD_NANDF_RB2__FEC_COL, - MX51_PAD_NANDF_RB3__FEC_RXCLK, - MX51_PAD_NANDF_RB6__FEC_RDAT0, - MX51_PAD_NANDF_RB7__FEC_TDAT0, + MX51_PAD_NANDF_RB3__FEC_RX_CLK, + MX51_PAD_NANDF_D9__FEC_RDATA0, + MX51_PAD_NANDF_D8__FEC_TDATA0, MX51_PAD_NANDF_CS2__FEC_TX_ER, MX51_PAD_NANDF_CS3__FEC_MDC, - MX51_PAD_NANDF_CS4__FEC_TDAT1, - MX51_PAD_NANDF_CS5__FEC_TDAT2, - MX51_PAD_NANDF_CS6__FEC_TDAT3, + MX51_PAD_NANDF_CS4__FEC_TDATA1, + MX51_PAD_NANDF_CS5__FEC_TDATA2, + MX51_PAD_NANDF_CS6__FEC_TDATA3, MX51_PAD_NANDF_CS7__FEC_TX_EN, MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK, /* FEC PHY reset line */ - MX51_PAD_EIM_A20__GPIO_2_14, + MX51_PAD_EIM_A20__GPIO2_14, /* SD 1 */ MX51_PAD_SD1_CMD__SD1_CMD, @@ -147,6 +151,13 @@ static struct pad_desc mx51babbage_pads[] = { MX51_PAD_SD2_DATA1__SD2_DATA1, MX51_PAD_SD2_DATA2__SD2_DATA2, MX51_PAD_SD2_DATA3__SD2_DATA3, + + /* eCSPI1 */ + MX51_PAD_CSPI1_MISO__ECSPI1_MISO, + MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, + MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, + MX51_PAD_CSPI1_SS0__GPIO4_24, + MX51_PAD_CSPI1_SS1__GPIO4_25, }; /* Serial ports */ @@ -177,12 +188,12 @@ static struct imxi2c_platform_data babbage_hsi2c_data = { static int gpio_usbh1_active(void) { - struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27; - struct pad_desc phyreset_gpio = MX51_PAD_EIM_D21__GPIO_2_5; + iomux_v3_cfg_t usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO1_27; + iomux_v3_cfg_t phyreset_gpio = MX51_PAD_EIM_D21__GPIO2_5; int ret; /* Set USBH1_STP to GPIO and toggle it */ - mxc_iomux_v3_setup_pad(&usbh1stp_gpio); + mxc_iomux_v3_setup_pad(usbh1stp_gpio); ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp"); if (ret) { @@ -195,7 +206,7 @@ static int gpio_usbh1_active(void) gpio_free(BABBAGE_USBH1_STP); /* De-assert USB PHY RESETB */ - mxc_iomux_v3_setup_pad(&phyreset_gpio); + mxc_iomux_v3_setup_pad(phyreset_gpio); ret = gpio_request(BABBAGE_PHY_RESET, "phy_reset"); if (ret) { @@ -251,6 +262,8 @@ static int initialize_otg_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* Set the PHY clock to 19.2MHz */ @@ -269,6 +282,8 @@ static int initialize_usbh1_port(struct platform_device *pdev) void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; /* The clock for the USBH1 ULPI port will come externally from the PHY. */ @@ -310,13 +325,35 @@ static int __init babbage_otg_mode(char *options) } __setup("otg_mode=", babbage_otg_mode); +static struct spi_board_info mx51_babbage_spi_board_info[] __initdata = { + { + .modalias = "mtd_dataflash", + .max_speed_hz = 25000000, + .bus_num = 0, + .chip_select = 1, + .mode = SPI_MODE_0, + .platform_data = NULL, + }, +}; + +static int mx51_babbage_spi_cs[] = { + BABBAGE_ECSPI1_CS0, + BABBAGE_ECSPI1_CS1, +}; + +static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = { + .chipselect = mx51_babbage_spi_cs, + .num_chipselect = ARRAY_SIZE(mx51_babbage_spi_cs), +}; + /* * Board specific initialization. */ static void __init mxc_board_init(void) { - struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP; - struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21; + iomux_v3_cfg_t usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP; + iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 | + MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP); #if defined(CONFIG_CPU_FREQ_IMX) get_cpu_op = mx51_get_cpu_op; @@ -328,8 +365,7 @@ static void __init mxc_board_init(void) imx51_add_fec(NULL); /* Set the PAD settings for the pwr key. */ - power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2; - mxc_iomux_v3_setup_pad(&power_key); + mxc_iomux_v3_setup_pad(power_key); imx51_add_gpio_keys(&imx_button_data); imx51_add_imx_i2c(0, &babbage_i2c_data); @@ -346,11 +382,16 @@ static void __init mxc_board_init(void) gpio_usbh1_active(); mxc_register_device(&mxc_usbh1_device, &usbh1_config); /* setback USBH1_STP to be function */ - mxc_iomux_v3_setup_pad(&usbh1stp); + mxc_iomux_v3_setup_pad(usbh1stp); babbage_usbhub_reset(); - imx51_add_esdhc(0, NULL); - imx51_add_esdhc(1, NULL); + imx51_add_sdhci_esdhc_imx(0, NULL); + imx51_add_sdhci_esdhc_imx(1, NULL); + + spi_register_board_info(mx51_babbage_spi_board_info, + ARRAY_SIZE(mx51_babbage_spi_board_info)); + imx51_add_ecspi(0, &mx51_babbage_spi_pdata); + imx51_add_imx2_wdt(0, NULL); } static void __init mx51_babbage_timer_init(void) diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c index 6e623bda3ee7..b7946f8e8d40 100644 --- a/arch/arm/mach-mx5/board-mx51_efikamx.c +++ b/arch/arm/mach-mx5/board-mx51_efikamx.c @@ -18,9 +18,13 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/gpio.h> +#include <linux/leds.h> +#include <linux/input.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/fsl_devices.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> #include <mach/common.h> #include <mach/hardware.h> @@ -39,12 +43,81 @@ #define MX51_USB_PLL_DIV_24_MHZ 0x01 -static struct pad_desc mx51efikamx_pads[] = { +#define EFIKAMX_PCBID0 IMX_GPIO_NR(3, 16) +#define EFIKAMX_PCBID1 IMX_GPIO_NR(3, 17) +#define EFIKAMX_PCBID2 IMX_GPIO_NR(3, 11) + +#define EFIKAMX_BLUE_LED IMX_GPIO_NR(3, 13) +#define EFIKAMX_GREEN_LED IMX_GPIO_NR(3, 14) +#define EFIKAMX_RED_LED IMX_GPIO_NR(3, 15) + +#define EFIKAMX_POWER_KEY IMX_GPIO_NR(2, 31) + +#define EFIKAMX_SPI_CS0 IMX_GPIO_NR(4, 24) +#define EFIKAMX_SPI_CS1 IMX_GPIO_NR(4, 25) + +/* board 1.1 doesn't have same reset gpio */ +#define EFIKAMX_RESET1_1 IMX_GPIO_NR(3, 2) +#define EFIKAMX_RESET IMX_GPIO_NR(1, 4) + +/* the pci ids pin have pull up. they're driven low according to board id */ +#define MX51_PAD_PCBID0 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, PAD_CTL_PUS_100K_UP) +#define MX51_PAD_PCBID1 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, PAD_CTL_PUS_100K_UP) +#define MX51_PAD_PCBID2 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, PAD_CTL_PUS_100K_UP) +#define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE) + +static iomux_v3_cfg_t mx51efikamx_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, MX51_PAD_UART1_TXD__UART1_TXD, MX51_PAD_UART1_RTS__UART1_RTS, MX51_PAD_UART1_CTS__UART1_CTS, + /* board id */ + MX51_PAD_PCBID0, + MX51_PAD_PCBID1, + MX51_PAD_PCBID2, + + /* SD 1 */ + MX51_PAD_SD1_CMD__SD1_CMD, + MX51_PAD_SD1_CLK__SD1_CLK, + MX51_PAD_SD1_DATA0__SD1_DATA0, + MX51_PAD_SD1_DATA1__SD1_DATA1, + MX51_PAD_SD1_DATA2__SD1_DATA2, + MX51_PAD_SD1_DATA3__SD1_DATA3, + + /* SD 2 */ + MX51_PAD_SD2_CMD__SD2_CMD, + MX51_PAD_SD2_CLK__SD2_CLK, + MX51_PAD_SD2_DATA0__SD2_DATA0, + MX51_PAD_SD2_DATA1__SD2_DATA1, + MX51_PAD_SD2_DATA2__SD2_DATA2, + MX51_PAD_SD2_DATA3__SD2_DATA3, + + /* SD/MMC WP/CD */ + MX51_PAD_GPIO1_0__SD1_CD, + MX51_PAD_GPIO1_1__SD1_WP, + MX51_PAD_GPIO1_7__SD2_WP, + MX51_PAD_GPIO1_8__SD2_CD, + + /* leds */ + MX51_PAD_CSI1_D9__GPIO3_13, + MX51_PAD_CSI1_VSYNC__GPIO3_14, + MX51_PAD_CSI1_HSYNC__GPIO3_15, + + /* power key */ + MX51_PAD_PWRKEY, + + /* spi */ + MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, + MX51_PAD_CSPI1_MISO__ECSPI1_MISO, + MX51_PAD_CSPI1_SS0__GPIO4_24, + MX51_PAD_CSPI1_SS1__GPIO4_25, + MX51_PAD_CSPI1_RDY__ECSPI1_RDY, + MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, + + /* reset */ + MX51_PAD_DI1_PIN13__GPIO3_2, + MX51_PAD_GPIO1_4__GPIO1_4, }; /* Serial ports */ @@ -75,6 +148,8 @@ static int initialize_otg_port(struct platform_device *pdev) void __iomem *usb_base; void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + if (!usb_base) + return -ENOMEM; usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET); /* Set the PHY clock to 19.2MHz */ @@ -92,12 +167,182 @@ static struct mxc_usbh_platform_data dr_utmi_config = { .flags = MXC_EHCI_INTERNAL_PHY, }; +/* PCBID2 PCBID1 PCBID0 STATE + 1 1 1 ER1:rev1.1 + 1 1 0 ER2:rev1.2 + 1 0 1 ER3:rev1.3 + 1 0 0 ER4:rev1.4 +*/ +static void __init mx51_efikamx_board_id(void) +{ + int id; + + /* things are taking time to settle */ + msleep(150); + + gpio_request(EFIKAMX_PCBID0, "pcbid0"); + gpio_direction_input(EFIKAMX_PCBID0); + gpio_request(EFIKAMX_PCBID1, "pcbid1"); + gpio_direction_input(EFIKAMX_PCBID1); + gpio_request(EFIKAMX_PCBID2, "pcbid2"); + gpio_direction_input(EFIKAMX_PCBID2); + + id = gpio_get_value(EFIKAMX_PCBID0); + id |= gpio_get_value(EFIKAMX_PCBID1) << 1; + id |= gpio_get_value(EFIKAMX_PCBID2) << 2; + + switch (id) { + case 7: + system_rev = 0x11; + break; + case 6: + system_rev = 0x12; + break; + case 5: + system_rev = 0x13; + break; + case 4: + system_rev = 0x14; + break; + default: + system_rev = 0x10; + break; + } + + if ((system_rev == 0x10) + || (system_rev == 0x12) + || (system_rev == 0x14)) { + printk(KERN_WARNING + "EfikaMX: Unsupported board revision 1.%u!\n", + system_rev & 0xf); + } +} + +static struct gpio_led mx51_efikamx_leds[] = { + { + .name = "efikamx:green", + .default_trigger = "default-on", + .gpio = EFIKAMX_GREEN_LED, + }, + { + .name = "efikamx:red", + .default_trigger = "ide-disk", + .gpio = EFIKAMX_RED_LED, + }, + { + .name = "efikamx:blue", + .default_trigger = "mmc0", + .gpio = EFIKAMX_BLUE_LED, + }, +}; + +static struct gpio_led_platform_data mx51_efikamx_leds_data = { + .leds = mx51_efikamx_leds, + .num_leds = ARRAY_SIZE(mx51_efikamx_leds), +}; + +static struct platform_device mx51_efikamx_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &mx51_efikamx_leds_data, + }, +}; + +static struct gpio_keys_button mx51_efikamx_powerkey[] = { + { + .code = KEY_POWER, + .gpio = EFIKAMX_POWER_KEY, + .type = EV_PWR, + .desc = "Power Button (CM)", + .wakeup = 1, + .debounce_interval = 10, /* ms */ + }, +}; + +static const struct gpio_keys_platform_data mx51_efikamx_powerkey_data __initconst = { + .buttons = mx51_efikamx_powerkey, + .nbuttons = ARRAY_SIZE(mx51_efikamx_powerkey), +}; + +static struct mtd_partition mx51_efikamx_spi_nor_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_256K, + }, + { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + }, +}; + +static struct flash_platform_data mx51_efikamx_spi_flash_data = { + .name = "spi_flash", + .parts = mx51_efikamx_spi_nor_partitions, + .nr_parts = ARRAY_SIZE(mx51_efikamx_spi_nor_partitions), + .type = "sst25vf032b", +}; + +static struct spi_board_info mx51_efikamx_spi_board_info[] __initdata = { + { + .modalias = "m25p80", + .max_speed_hz = 25000000, + .bus_num = 0, + .chip_select = 1, + .platform_data = &mx51_efikamx_spi_flash_data, + .irq = -1, + }, +}; + +static int mx51_efikamx_spi_cs[] = { + EFIKAMX_SPI_CS0, + EFIKAMX_SPI_CS1, +}; + +static const struct spi_imx_master mx51_efikamx_spi_pdata __initconst = { + .chipselect = mx51_efikamx_spi_cs, + .num_chipselect = ARRAY_SIZE(mx51_efikamx_spi_cs), +}; + +void mx51_efikamx_reset(void) +{ + if (system_rev == 0x11) + gpio_direction_output(EFIKAMX_RESET1_1, 0); + else + gpio_direction_output(EFIKAMX_RESET, 0); +} + static void __init mxc_board_init(void) { mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads, ARRAY_SIZE(mx51efikamx_pads)); + mx51_efikamx_board_id(); mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); mxc_init_imx_uart(); + imx51_add_sdhci_esdhc_imx(0, NULL); + + /* on < 1.2 boards both SD controllers are used */ + if (system_rev < 0x12) { + imx51_add_sdhci_esdhc_imx(1, NULL); + mx51_efikamx_leds[2].default_trigger = "mmc1"; + } + + platform_device_register(&mx51_efikamx_leds_device); + imx51_add_gpio_keys(&mx51_efikamx_powerkey_data); + + spi_register_board_info(mx51_efikamx_spi_board_info, + ARRAY_SIZE(mx51_efikamx_spi_board_info)); + imx51_add_ecspi(0, &mx51_efikamx_spi_pdata); + + if (system_rev == 0x11) { + gpio_request(EFIKAMX_RESET1_1, "reset"); + gpio_direction_output(EFIKAMX_RESET1_1, 1); + } else { + gpio_request(EFIKAMX_RESET, "reset"); + gpio_direction_output(EFIKAMX_RESET, 1); + } } static void __init mx51_efikamx_timer_init(void) diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c new file mode 100644 index 000000000000..caee04c08238 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx53_evk.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org> + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/fec.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx53.h> + +#define SMD_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) + +#include "crm_regs.h" +#include "devices-imx53.h" + +static iomux_v3_cfg_t mx53_evk_pads[] = { + MX53_PAD_CSI0_D10__UART1_TXD, + MX53_PAD_CSI0_D11__UART1_RXD, + MX53_PAD_ATA_DIOW__UART1_TXD, + MX53_PAD_ATA_DMACK__UART1_RXD, + + MX53_PAD_ATA_BUFFER_EN__UART2_RXD, + MX53_PAD_ATA_DMARQ__UART2_TXD, + MX53_PAD_ATA_DIOR__UART2_RTS, + MX53_PAD_ATA_INTRQ__UART2_CTS, + + MX53_PAD_ATA_CS_0__UART3_TXD, + MX53_PAD_ATA_CS_1__UART3_RXD, + MX53_PAD_ATA_DA_1__UART3_CTS, + MX53_PAD_ATA_DA_2__UART3_RTS, + + MX53_PAD_EIM_D16__CSPI1_SCLK, + MX53_PAD_EIM_D17__CSPI1_MISO, + MX53_PAD_EIM_D18__CSPI1_MOSI, + + /* ecspi chip select lines */ + MX53_PAD_EIM_EB2__GPIO_2_30, + MX53_PAD_EIM_D19__GPIO_3_19, +}; + +static const struct imxuart_platform_data mx53_evk_uart_pdata __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static inline void mx53_evk_init_uart(void) +{ + imx53_add_imx_uart(0, &mx53_evk_uart_pdata); + imx53_add_imx_uart(1, &mx53_evk_uart_pdata); + imx53_add_imx_uart(2, &mx53_evk_uart_pdata); +} + +static const struct imxi2c_platform_data mx53_evk_i2c_data __initconst = { + .bitrate = 100000, +}; + +static inline void mx53_evk_fec_reset(void) +{ + int ret; + + /* reset FEC PHY */ + ret = gpio_request(SMD_FEC_PHY_RST, "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); +} + +static struct fec_platform_data mx53_evk_fec_pdata = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static struct spi_board_info mx53_evk_spi_board_info[] __initdata = { + { + .modalias = "mtd_dataflash", + .max_speed_hz = 25000000, + .bus_num = 0, + .chip_select = 1, + .mode = SPI_MODE_0, + .platform_data = NULL, + }, +}; + +static int mx53_evk_spi_cs[] = { + EVK_ECSPI1_CS0, + EVK_ECSPI1_CS1, +}; + +static const struct spi_imx_master mx53_evk_spi_data __initconst = { + .chipselect = mx53_evk_spi_cs, + .num_chipselect = ARRAY_SIZE(mx53_evk_spi_cs), +}; + +static void __init mx53_evk_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads, + ARRAY_SIZE(mx53_evk_pads)); + mx53_evk_init_uart(); + mx53_evk_fec_reset(); + imx53_add_fec(&mx53_evk_fec_pdata); + + imx53_add_imx_i2c(0, &mx53_evk_i2c_data); + imx53_add_imx_i2c(1, &mx53_evk_i2c_data); + + imx53_add_sdhci_esdhc_imx(0, NULL); + imx53_add_sdhci_esdhc_imx(1, NULL); + + spi_register_board_info(mx53_evk_spi_board_info, + ARRAY_SIZE(mx53_evk_spi_board_info)); + imx53_add_ecspi(0, &mx53_evk_spi_data); +} + +static void __init mx53_evk_timer_init(void) +{ + mx53_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mx53_evk_timer = { + .init = mx53_evk_timer_init, +}; + +MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board") + .map_io = mx53_map_io, + .init_irq = mx53_init_irq, + .init_machine = mx53_evk_board_init, + .timer = &mx53_evk_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c new file mode 100644 index 000000000000..d1348e04ace3 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx53_loco.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/fec.h> +#include <linux/delay.h> +#include <linux/gpio.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx53.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "crm_regs.h" +#include "devices-imx53.h" + +#define LOCO_FEC_PHY_RST IMX_GPIO_NR(7, 6) + +static iomux_v3_cfg_t mx53_loco_pads[] = { + MX53_PAD_CSI0_D10__UART1_TXD, + MX53_PAD_CSI0_D11__UART1_RXD, + MX53_PAD_ATA_DIOW__UART1_TXD, + MX53_PAD_ATA_DMACK__UART1_RXD, + + MX53_PAD_ATA_BUFFER_EN__UART2_RXD, + MX53_PAD_ATA_DMARQ__UART2_TXD, + MX53_PAD_ATA_DIOR__UART2_RTS, + MX53_PAD_ATA_INTRQ__UART2_CTS, + + MX53_PAD_ATA_CS_0__UART3_TXD, + MX53_PAD_ATA_CS_1__UART3_RXD, + MX53_PAD_ATA_DA_1__UART3_CTS, + MX53_PAD_ATA_DA_2__UART3_RTS, +}; + +static const struct imxuart_platform_data mx53_loco_uart_data __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static inline void mx53_loco_init_uart(void) +{ + imx53_add_imx_uart(0, &mx53_loco_uart_data); + imx53_add_imx_uart(1, &mx53_loco_uart_data); + imx53_add_imx_uart(2, &mx53_loco_uart_data); +} + +static inline void mx53_loco_fec_reset(void) +{ + int ret; + + /* reset FEC PHY */ + ret = gpio_request(LOCO_FEC_PHY_RST, "fec-phy-reset"); + if (ret) { + printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret); + return; + } + gpio_direction_output(LOCO_FEC_PHY_RST, 0); + msleep(1); + gpio_set_value(LOCO_FEC_PHY_RST, 1); +} + +static struct fec_platform_data mx53_loco_fec_data = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static void __init mx53_loco_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads, + ARRAY_SIZE(mx53_loco_pads)); + mx53_loco_init_uart(); + mx53_loco_fec_reset(); + imx53_add_fec(&mx53_loco_fec_data); +} + +static void __init mx53_loco_timer_init(void) +{ + mx53_clocks_init(32768, 24000000, 0, 0); +} + +static struct sys_timer mx53_loco_timer = { + .init = mx53_loco_timer_init, +}; + +MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board") + .map_io = mx53_map_io, + .init_irq = mx53_init_irq, + .init_machine = mx53_loco_board_init, + .timer = &mx53_loco_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c new file mode 100644 index 000000000000..7970f7a48588 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx53_smd.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/fec.h> +#include <linux/delay.h> +#include <linux/gpio.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx53.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "crm_regs.h" +#include "devices-imx53.h" + +#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6) + +static iomux_v3_cfg_t mx53_smd_pads[] = { + MX53_PAD_CSI0_D10__UART1_TXD, + MX53_PAD_CSI0_D11__UART1_RXD, + MX53_PAD_ATA_DIOW__UART1_TXD, + MX53_PAD_ATA_DMACK__UART1_RXD, + + MX53_PAD_ATA_BUFFER_EN__UART2_RXD, + MX53_PAD_ATA_DMARQ__UART2_TXD, + MX53_PAD_ATA_DIOR__UART2_RTS, + MX53_PAD_ATA_INTRQ__UART2_CTS, + + MX53_PAD_ATA_CS_0__UART3_TXD, + MX53_PAD_ATA_CS_1__UART3_RXD, + MX53_PAD_ATA_DA_1__UART3_CTS, + MX53_PAD_ATA_DA_2__UART3_RTS, +}; + +static const struct imxuart_platform_data mx53_smd_uart_data __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static inline void mx53_smd_init_uart(void) +{ + imx53_add_imx_uart(0, &mx53_smd_uart_data); + imx53_add_imx_uart(1, &mx53_smd_uart_data); + imx53_add_imx_uart(2, &mx53_smd_uart_data); +} + +static inline void mx53_smd_fec_reset(void) +{ + int ret; + + /* reset FEC PHY */ + ret = gpio_request(SMD_FEC_PHY_RST, "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); + msleep(1); + gpio_set_value(SMD_FEC_PHY_RST, 1); +} + +static struct fec_platform_data mx53_smd_fec_data = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static void __init mx53_smd_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads, + ARRAY_SIZE(mx53_smd_pads)); + mx53_smd_init_uart(); + mx53_smd_fec_reset(); + imx53_add_fec(&mx53_smd_fec_data); +} + +static void __init mx53_smd_timer_init(void) +{ + mx53_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mx53_smd_timer = { + .init = mx53_smd_timer_init, +}; + +MACHINE_START(MX53_SMD, "Freescale MX53 SMD Board") + .map_io = mx53_map_io, + .init_irq = mx53_init_irq, + .init_machine = mx53_smd_board_init, + .timer = &mx53_smd_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 8ac36d882927..0a19e7567c0b 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -14,8 +14,8 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/clkdev.h> -#include <asm/clkdev.h> #include <asm/div64.h> #include <mach/hardware.h> @@ -33,11 +33,15 @@ static struct clk pll1_main_clk; static struct clk pll1_sw_clk; static struct clk pll2_sw_clk; static struct clk pll3_sw_clk; +static struct clk mx53_pll4_sw_clk; static struct clk lp_apm_clk; static struct clk periph_apm_clk; static struct clk ahb_clk; static struct clk ipg_clk; static struct clk usboh3_clk; +static struct clk emi_fast_clk; +static struct clk ipu_clk; +static struct clk mipi_hsc1_clk; #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ @@ -123,7 +127,7 @@ static inline u32 _get_mux(struct clk *parent, struct clk *m0, return -EINVAL; } -static inline void __iomem *_get_pll_base(struct clk *pll) +static inline void __iomem *_mx51_get_pll_base(struct clk *pll) { if (pll == &pll1_main_clk) return MX51_DPLL1_BASE; @@ -137,6 +141,30 @@ static inline void __iomem *_get_pll_base(struct clk *pll) return NULL; } +static inline void __iomem *_mx53_get_pll_base(struct clk *pll) +{ + if (pll == &pll1_main_clk) + return MX53_DPLL1_BASE; + else if (pll == &pll2_sw_clk) + return MX53_DPLL2_BASE; + else if (pll == &pll3_sw_clk) + return MX53_DPLL3_BASE; + else if (pll == &mx53_pll4_sw_clk) + return MX53_DPLL4_BASE; + else + BUG(); + + return NULL; +} + +static inline void __iomem *_get_pll_base(struct clk *pll) +{ + if (cpu_is_mx51()) + return _mx51_get_pll_base(pll); + else + return _mx53_get_pll_base(pll); +} + static unsigned long clk_pll_get_rate(struct clk *clk) { long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; @@ -514,7 +542,10 @@ static int _clk_max_enable(struct clk *clk) /* Handshake with MAX when LPM is entered. */ reg = __raw_readl(MXC_CCM_CLPCR); - reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; + if (cpu_is_mx51()) + reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; + else if (cpu_is_mx53()) + reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); return 0; @@ -528,7 +559,10 @@ static void _clk_max_disable(struct clk *clk) /* No Handshake with MAX when LPM is entered as its disabled. */ reg = __raw_readl(MXC_CCM_CLPCR); - reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; + if (cpu_is_mx51()) + reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; + else if (cpu_is_mx53()) + reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); } @@ -679,6 +713,19 @@ static unsigned long clk_emi_slow_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / div; } +static unsigned long _clk_ddr_hf_get_rate(struct clk *clk) +{ + unsigned long rate; + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >> + MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1; + rate = clk_get_rate(clk->parent) / div; + + return rate; +} + /* External high frequency clock */ static struct clk ckih_clk = { .get_rate = get_high_reference_clock_rate, @@ -739,6 +786,14 @@ static struct clk pll3_sw_clk = { .disable = _clk_pll_disable, }; +/* PLL4 SW supplies to LVDS Display Bridge(LDB) */ +static struct clk mx53_pll4_sw_clk = { + .parent = &osc_clk, + .set_rate = _clk_pll_set_rate, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, +}; + /* Low-power Audio Playback Mode clock */ static struct clk lp_apm_clk = { .parent = &osc_clk, @@ -763,6 +818,12 @@ static struct clk ahb_clk = { .round_rate = _clk_ahb_round_rate, }; +static struct clk iim_clk = { + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET, +}; + /* Main IP interface clock for access to registers */ static struct clk ipg_clk = { .parent = &ahb_clk, @@ -810,6 +871,10 @@ static struct clk kpp_clk = { .id = 0, }; +static struct clk dummy_clk = { + .id = 0, +}; + static struct clk emi_slow_clk = { .parent = &pll2_sw_clk, .enable_reg = MXC_CCM_CCGR5, @@ -819,6 +884,109 @@ static struct clk emi_slow_clk = { .get_rate = clk_emi_slow_get_rate, }; +static int clk_ipu_enable(struct clk *clk) +{ + u32 reg; + + _clk_ccgr_enable(clk); + + /* Enable handshake with IPU when certain clock rates are changed */ + reg = __raw_readl(MXC_CCM_CCDR); + reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + /* Enable handshake with IPU when LPM is entered */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static void clk_ipu_disable(struct clk *clk) +{ + u32 reg; + + _clk_ccgr_disable(clk); + + /* Disable handshake with IPU whe dividers are changed */ + reg = __raw_readl(MXC_CCM_CCDR); + reg |= MXC_CCM_CCDR_IPU_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + /* Disable handshake with IPU when LPM is entered */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + +static struct clk ahbmux1_clk = { + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, + .enable = _clk_ccgr_enable, + .disable = _clk_ccgr_disable_inwait, +}; + +static struct clk ipu_sec_clk = { + .parent = &emi_fast_clk, + .secondary = &ahbmux1_clk, +}; + +static struct clk ddr_hf_clk = { + .parent = &pll1_sw_clk, + .get_rate = _clk_ddr_hf_get_rate, +}; + +static struct clk ddr_clk = { + .parent = &ddr_hf_clk, +}; + +/* clock definitions for MIPI HSC unit which has been removed + * from documentation, but not from hardware + */ +static int _clk_hsc_enable(struct clk *clk) +{ + u32 reg; + + _clk_ccgr_enable(clk); + /* Handshake with IPU when certain clock rates are changed. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg &= ~MXC_CCM_CCDR_HSC_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static void _clk_hsc_disable(struct clk *clk) +{ + u32 reg; + + _clk_ccgr_disable(clk); + /* No handshake with HSC as its not enabled. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg |= MXC_CCM_CCDR_HSC_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + +static struct clk mipi_hsp_clk = { + .parent = &ipu_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET, + .enable = _clk_hsc_enable, + .disable = _clk_hsc_disable, + .secondary = &mipi_hsc1_clk, +}; + #define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ static struct clk name = { \ .id = i, \ @@ -927,6 +1095,41 @@ static struct clk usboh3_clk = { .parent = &pll2_sw_clk, .get_rate = clk_usboh3_get_rate, .set_parent = clk_usboh3_set_parent, + .enable = _clk_ccgr_enable, + .disable = _clk_ccgr_disable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, +}; + +static struct clk usb_ahb_clk = { + .parent = &ipg_clk, + .enable = _clk_ccgr_enable, + .disable = _clk_ccgr_disable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, +}; + +static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; + + if (parent == &pll3_sw_clk) + reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET; + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk usb_phy1_clk = { + .parent = &pll3_sw_clk, + .set_parent = clk_usb_phy1_set_parent, + .enable = _clk_ccgr_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, + .disable = _clk_ccgr_disable, }; /* eCSPI */ @@ -988,6 +1191,11 @@ DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, NULL, NULL, &ipg_clk, &gpt_ipg_clk); +DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET, + NULL, NULL, &ipg_clk, NULL); + /* I2C */ DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -1013,6 +1221,10 @@ DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET, NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk); +DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET, + NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk); /* eCSPI */ DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, @@ -1046,6 +1258,23 @@ DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET, DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); +DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); +DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); +DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); + +/* IPU */ +DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET, + NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk); + +DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET, + NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait, + &ddr_clk, NULL); + +DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET, + NULL, NULL, &pll3_sw_clk, NULL); +DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET, + NULL, NULL, &pll3_sw_clk, NULL); + #define _REGISTER_CLOCK(d, n, c) \ { \ .dev_id = d, \ @@ -1053,25 +1282,31 @@ DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, .clk = &c, \ }, -static struct clk_lookup lookups[] = { +static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) + _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) - _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk) + _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk) + _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk) _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) - _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk) + _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk) + _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk) + _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) - _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk) + _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk) _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk) _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) + _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) _REGISTER_CLOCK(NULL, "ckih", ckih_clk) _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) @@ -1082,6 +1317,29 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) + _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) + _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) + _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) + _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk) + _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk) + _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk) + _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) +}; + +static struct clk_lookup mx53_lookups[] = { + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK(NULL, "gpt", gpt_clk) + _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) + _REGISTER_CLOCK("imx53-ecspi.0", NULL, ecspi1_clk) + _REGISTER_CLOCK("imx53-ecspi.1", NULL, ecspi2_clk) + _REGISTER_CLOCK("imx53-cspi.0", NULL, cspi_clk) }; static void clk_tree_init(void) @@ -1114,14 +1372,21 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, ckih2_reference = ckih2; oscillator_reference = osc; - for (i = 0; i < ARRAY_SIZE(lookups); i++) - clkdev_add(&lookups[i]); + for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) + clkdev_add(&mx51_lookups[i]); clk_tree_init(); clk_enable(&cpu_clk); clk_enable(&main_bus_clk); + clk_enable(&iim_clk); + mx51_revision(); + clk_disable(&iim_clk); + + /* move usb_phy_clk to 24MHz */ + clk_set_parent(&usb_phy1_clk, &osc_clk); + /* set the usboh3_clk parent to pll2_sw_clk */ clk_set_parent(&usboh3_clk, &pll2_sw_clk); @@ -1138,3 +1403,32 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, MX51_MXC_INT_GPT); return 0; } + +int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, + unsigned long ckih1, unsigned long ckih2) +{ + int i; + + external_low_reference = ckil; + external_high_reference = ckih1; + ckih2_reference = ckih2; + oscillator_reference = osc; + + for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++) + clkdev_add(&mx53_lookups[i]); + + clk_tree_init(); + + clk_set_parent(&uart_root_clk, &pll3_sw_clk); + clk_enable(&cpu_clk); + clk_enable(&main_bus_clk); + + clk_enable(&iim_clk); + mx53_revision(); + clk_disable(&iim_clk); + + /* System timer */ + mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), + MX53_INT_GPT); + return 0; +} diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index eaacb6e9b5d0..d40671da4372 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2010 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 @@ -20,37 +20,18 @@ static int cpu_silicon_rev = -1; -#define SI_REV 0x48 +#define IIM_SREV 0x24 -static void query_silicon_parameter(void) +static int get_mx51_srev(void) { - void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE); - u32 rev; + void __iomem *iim_base = MX51_IO_ADDRESS(MX51_IIM_BASE_ADDR); + u32 rev = readl(iim_base + IIM_SREV) & 0xff; - if (!rom) { - cpu_silicon_rev = -EINVAL; - return; - } - - rev = readl(rom + SI_REV); - switch (rev) { - case 0x1: - cpu_silicon_rev = MX51_CHIP_REV_1_0; - break; - case 0x2: - cpu_silicon_rev = MX51_CHIP_REV_1_1; - break; - case 0x10: - cpu_silicon_rev = MX51_CHIP_REV_2_0; - break; - case 0x20: - cpu_silicon_rev = MX51_CHIP_REV_3_0; - break; - default: - cpu_silicon_rev = 0; - } - - iounmap(rom); + if (rev == 0x0) + return IMX_CHIP_REVISION_2_0; + else if (rev == 0x10) + return IMX_CHIP_REVISION_3_0; + return 0; } /* @@ -64,7 +45,7 @@ int mx51_revision(void) return -EINVAL; if (cpu_silicon_rev == -1) - query_silicon_parameter(); + cpu_silicon_rev = get_mx51_srev(); return cpu_silicon_rev; } @@ -79,7 +60,10 @@ EXPORT_SYMBOL(mx51_revision); */ static int __init mx51_neon_fixup(void) { - if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) { + if (!cpu_is_mx51()) + return 0; + + if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) { elf_hwcap &= ~HWCAP_NEON; pr_info("Turning off NEON support, detected broken NEON implementation\n"); } @@ -89,29 +73,65 @@ static int __init mx51_neon_fixup(void) late_initcall(mx51_neon_fixup); #endif +static int get_mx53_srev(void) +{ + void __iomem *iim_base = MX51_IO_ADDRESS(MX53_IIM_BASE_ADDR); + u32 rev = readl(iim_base + IIM_SREV) & 0xff; + + if (rev == 0x0) + return IMX_CHIP_REVISION_1_0; + else if (rev == 0x10) + return IMX_CHIP_REVISION_2_0; + return 0; +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx53 + */ +int mx53_revision(void) +{ + if (!cpu_is_mx53()) + return -EINVAL; + + if (cpu_silicon_rev == -1) + cpu_silicon_rev = get_mx53_srev(); + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx53_revision); + static int __init post_cpu_init(void) { unsigned int reg; void __iomem *base; - if (!cpu_is_mx51()) - return 0; - - base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR); - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); - - base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR); - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); + if (cpu_is_mx51() || cpu_is_mx53()) { + if (cpu_is_mx51()) + base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR); + else + base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR); + + __raw_writel(0x0, base + 0x40); + __raw_writel(0x0, base + 0x44); + __raw_writel(0x0, base + 0x48); + __raw_writel(0x0, base + 0x4C); + reg = __raw_readl(base + 0x50) & 0x00FFFFFF; + __raw_writel(reg, base + 0x50); + + if (cpu_is_mx51()) + base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR); + else + base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR); + + __raw_writel(0x0, base + 0x40); + __raw_writel(0x0, base + 0x44); + __raw_writel(0x0, base + 0x48); + __raw_writel(0x0, base + 0x4C); + reg = __raw_readl(base + 0x50) & 0x00FFFFFF; + __raw_writel(reg, base + 0x50); + } return 0; } diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h index c776b9af0624..b462c22f53d8 100644 --- a/arch/arm/mach-mx5/crm_regs.h +++ b/arch/arm/mach-mx5/crm_regs.h @@ -18,6 +18,13 @@ #define MX51_CORTEXA8_BASE MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR) #define MX51_GPC_BASE MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR) +/*MX53*/ +#define MX53_CCM_BASE MX53_IO_ADDRESS(MX53_CCM_BASE_ADDR) +#define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) +#define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) +#define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) +#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) + /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 #define MXC_PLL_DP_CONFIG 0x04 @@ -380,7 +387,8 @@ /* Define the bits in register CLPCR */ #define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23) #define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22) -#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21) +#define MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21) +#define MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 25) #define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20) #define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19) #define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18) diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h index 8c50cb5d05f5..7fff485e5603 100644 --- a/arch/arm/mach-mx5/devices-imx51.h +++ b/arch/arm/mach-mx5/devices-imx51.h @@ -31,6 +31,11 @@ extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst; #define imx51_add_mxc_nand(pdata) \ imx_add_mxc_nand(&imx51_mxc_nand_data, pdata) +extern const struct imx_sdhci_esdhc_imx_data +imx51_sdhci_esdhc_imx_data[] __initconst; +#define imx51_add_sdhci_esdhc_imx(id, pdata) \ + imx_add_sdhci_esdhc_imx(&imx51_sdhci_esdhc_imx_data[id], pdata) + extern const struct imx_spi_imx_data imx51_cspi_data __initconst; #define imx51_add_cspi(pdata) \ imx_add_spi_imx(&imx51_cspi_data, pdata) @@ -39,6 +44,14 @@ extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst; #define imx51_add_ecspi(id, pdata) \ imx_add_spi_imx(&imx51_ecspi_data[id], pdata) -extern const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst; -#define imx51_add_esdhc(id, pdata) \ - imx_add_esdhc(&imx51_esdhc_data[id], pdata) +extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[] __initconst; +#define imx51_add_imx2_wdt(id, pdata) \ + imx_add_imx2_wdt(&imx51_imx2_wdt_data[id]) + +extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[] __initconst; +#define imx51_add_mxc_pwm(id) \ + imx_add_mxc_pwm(&imx51_mxc_pwm_data[id]) + +extern const struct imx_imx_keypad_data imx51_imx_keypad_data __initconst; +#define imx51_add_imx_keypad(pdata) \ + imx_add_imx_keypad(&imx51_imx_keypad_data, pdata) diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h new file mode 100644 index 000000000000..8639735a117b --- /dev/null +++ b/arch/arm/mach-mx5/devices-imx53.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org> + * + * 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 <mach/mx53.h> +#include <mach/devices-common.h> + +extern const struct imx_fec_data imx53_fec_data __initconst; +#define imx53_add_fec(pdata) \ + imx_add_fec(&imx53_fec_data, pdata) + +extern const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst; +#define imx53_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx53_imx_uart_data[id], pdata) + + +extern const struct imx_imx_i2c_data imx53_imx_i2c_data[] __initconst; +#define imx53_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx53_imx_i2c_data[id], pdata) + +extern const struct imx_sdhci_esdhc_imx_data +imx53_sdhci_esdhc_imx_data[] __initconst; +#define imx53_add_sdhci_esdhc_imx(id, pdata) \ + imx_add_sdhci_esdhc_imx(&imx53_sdhci_esdhc_imx_data[id], pdata) + +extern const struct imx_spi_imx_data imx53_ecspi_data[] __initconst; +#define imx53_add_ecspi(id, pdata) \ + imx_add_spi_imx(&imx53_ecspi_data[id], pdata) diff --git a/arch/arm/mach-mx5/devices-mx50.h b/arch/arm/mach-mx5/devices-mx50.h new file mode 100644 index 000000000000..98ab07468a0e --- /dev/null +++ b/arch/arm/mach-mx5/devices-mx50.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <mach/mx50.h> +#include <mach/devices-common.h> + +extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst; +#define imx50_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx50_imx_uart_data[id], pdata) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 4c7be87a7c9d..153ada53e575 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -97,38 +97,27 @@ struct platform_device mxc_usbh1_device = { }, }; -static struct resource mxc_wdt_resources[] = { +static struct resource usbh2_resources[] = { { - .start = MX51_WDOG_BASE_ADDR, - .end = MX51_WDOG_BASE_ADDR + SZ_16K - 1, + .start = MX51_OTG_BASE_ADDR + 0x400, + .end = MX51_OTG_BASE_ADDR + 0x400 + 0x1ff, .flags = IORESOURCE_MEM, }, -}; - -struct platform_device mxc_wdt = { - .name = "imx2-wdt", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_wdt_resources), - .resource = mxc_wdt_resources, -}; - -static struct resource mxc_kpp_resources[] = { { - .start = MX51_MXC_INT_KPP, - .end = MX51_MXC_INT_KPP, + .start = MX51_MXC_INT_USB_H2, .flags = IORESOURCE_IRQ, - } , { - .start = MX51_KPP_BASE_ADDR, - .end = MX51_KPP_BASE_ADDR + 0x8 - 1, - .flags = IORESOURCE_MEM, }, }; -struct platform_device mxc_keypad_device = { - .name = "imx-keypad", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_kpp_resources), - .resource = mxc_kpp_resources, +struct platform_device mxc_usbh2_device = { + .name = "mxc-ehci", + .id = 2, + .num_resources = ARRAY_SIZE(usbh2_resources), + .resource = usbh2_resources, + .dev = { + .dma_mask = &usb_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, }; static struct mxc_gpio_port mxc_gpio_ports[] = { @@ -160,9 +149,36 @@ static struct mxc_gpio_port mxc_gpio_ports[] = { .irq_high = MX51_MXC_INT_GPIO4_HIGH, .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3 }, + { + .chip.label = "gpio-4", + .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR), + .irq = MX53_INT_GPIO5_LOW, + .irq_high = MX53_INT_GPIO5_HIGH, + .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4 + }, + { + .chip.label = "gpio-5", + .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR), + .irq = MX53_INT_GPIO6_LOW, + .irq_high = MX53_INT_GPIO6_HIGH, + .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5 + }, + { + .chip.label = "gpio-6", + .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR), + .irq = MX53_INT_GPIO7_LOW, + .irq_high = MX53_INT_GPIO7_HIGH, + .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6 + }, }; int __init imx51_register_gpios(void) { + return mxc_gpio_init(mxc_gpio_ports, 4); +} + +int __init imx53_register_gpios(void) +{ return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); } + diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index af1d07c0bbc1..55a5129bc29f 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -1,6 +1,5 @@ extern struct platform_device mxc_usbdr_host_device; extern struct platform_device mxc_usbh1_device; +extern struct platform_device mxc_usbh2_device; extern struct platform_device mxc_usbdr_udc_device; -extern struct platform_device mxc_wdt; extern struct platform_device mxc_hsi2c_device; -extern struct platform_device mxc_keypad_device; diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c index a2e6e8c39d25..e83ffadb65f8 100644 --- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c +++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c @@ -21,7 +21,6 @@ #include <linux/fsl_devices.h> #include <linux/i2c/tsc2007.h> #include <linux/leds.h> -#include <linux/input/matrix_keypad.h> #include <mach/common.h> #include <mach/hardware.h> @@ -33,12 +32,12 @@ #include "devices-imx51.h" #include "devices.h" -#define MBIMX51_TSC2007_GPIO (2*32 + 30) +#define MBIMX51_TSC2007_GPIO IMX_GPIO_NR(3, 30) #define MBIMX51_TSC2007_IRQ (MXC_INTERNAL_IRQS + MBIMX51_TSC2007_GPIO) -#define MBIMX51_LED0 (2*32 + 5) -#define MBIMX51_LED1 (2*32 + 6) -#define MBIMX51_LED2 (2*32 + 7) -#define MBIMX51_LED3 (2*32 + 8) +#define MBIMX51_LED0 IMX_GPIO_NR(3, 5) +#define MBIMX51_LED1 IMX_GPIO_NR(3, 6) +#define MBIMX51_LED2 IMX_GPIO_NR(3, 7) +#define MBIMX51_LED3 IMX_GPIO_NR(3, 8) static struct gpio_led mbimx51_leds[] = { { @@ -84,7 +83,7 @@ static struct platform_device *devices[] __initdata = { &mbimx51_leds_gpio, }; -static struct pad_desc mbimx51_pads[] = { +static iomux_v3_cfg_t mbimx51_pads[] = { /* UART2 */ MX51_PAD_UART2_RXD__UART2_RXD, MX51_PAD_UART2_TXD__UART2_TXD, @@ -96,13 +95,13 @@ static struct pad_desc mbimx51_pads[] = { MX51_PAD_KEY_COL5__UART3_CTS, /* TSC2007 IRQ */ - MX51_PAD_NANDF_D10__GPIO_3_30, + MX51_PAD_NANDF_D10__GPIO3_30, /* LEDS */ - MX51_PAD_DISPB2_SER_DIN__GPIO_3_5, - MX51_PAD_DISPB2_SER_DIO__GPIO_3_6, - MX51_PAD_DISPB2_SER_CLK__GPIO_3_7, - MX51_PAD_DISPB2_SER_RS__GPIO_3_8, + MX51_PAD_DISPB2_SER_DIN__GPIO3_5, + MX51_PAD_DISPB2_SER_DIO__GPIO3_6, + MX51_PAD_DISPB2_SER_CLK__GPIO3_7, + MX51_PAD_DISPB2_SER_RS__GPIO3_8, /* KPP */ MX51_PAD_KEY_ROW0__KEY_ROW0, @@ -157,7 +156,7 @@ static int mbimx51_keymap[] = { KEY(3, 3, KEY_ENTER), }; -static struct matrix_keymap_data mbimx51_map_data = { +static const struct matrix_keymap_data mbimx51_map_data __initconst = { .keymap = mbimx51_keymap, .keymap_size = ARRAY_SIZE(mbimx51_keymap), }; @@ -209,7 +208,7 @@ void __init eukrea_mbimx51_baseboard_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); - mxc_register_device(&mxc_keypad_device, &mbimx51_map_data); + imx51_add_imx_keypad(&mbimx51_map_data); gpio_request(MBIMX51_TSC2007_GPIO, "tsc2007_irq"); gpio_direction_input(MBIMX51_TSC2007_GPIO); @@ -217,6 +216,6 @@ void __init eukrea_mbimx51_baseboard_init(void) i2c_register_board_info(1, mbimx51_i2c_devices, ARRAY_SIZE(mbimx51_i2c_devices)); - imx51_add_esdhc(0, NULL); - imx51_add_esdhc(1, NULL); + imx51_add_sdhci_esdhc_imx(0, NULL); + imx51_add_sdhci_esdhc_imx(1, NULL); } diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c index 2b48f5190830..c372a4373691 100644 --- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c @@ -45,14 +45,13 @@ #include "devices-imx51.h" #include "devices.h" -#define MBIMXSD_GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, \ - MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP) - -static struct pad_desc eukrea_mbimxsd_pads[] = { +static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = { /* LED */ - MX51_PAD_NANDF_D10__GPIO_3_30, + MX51_PAD_NANDF_D10__GPIO3_30, /* SWITCH */ - MBIMXSD_GPIO_3_31, + _MX51_PAD_NANDF_D9__GPIO3_31 | 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), /* UART2 */ MX51_PAD_UART2_RXD__UART2_RXD, MX51_PAD_UART2_TXD__UART2_TXD, @@ -70,8 +69,8 @@ static struct pad_desc eukrea_mbimxsd_pads[] = { MX51_PAD_SD1_DATA3__SD1_DATA3, }; -#define GPIO_LED1 (2 * 32 + 30) -#define GPIO_SWITCH1 (2 * 32 + 31) +#define GPIO_LED1 IMX_GPIO_NR(3, 30) +#define GPIO_SWITCH1 IMX_GPIO_NR(3, 31) static struct gpio_led eukrea_mbimxsd_leds[] = { { @@ -149,7 +148,7 @@ void __init eukrea_mbimxsd51_baseboard_init(void) imx51_add_imx_uart(1, NULL); imx51_add_imx_uart(2, &uart_pdata); - imx51_add_esdhc(0, NULL); + imx51_add_sdhci_esdhc_imx(0, NULL); gpio_request(GPIO_LED1, "LED1"); gpio_direction_output(GPIO_LED1, 1); diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c new file mode 100644 index 000000000000..8c6540e58390 --- /dev/null +++ b/arch/arm/mach-mx5/mm-mx50.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Create static mapping between physical to virtual memory. + */ + +#include <linux/mm.h> +#include <linux/init.h> + +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/iomux-v3.h> + +/* + * Define the MX50 memory map. + */ +static struct map_desc mx50_io_desc[] __initdata = { + imx_map_entry(MX50, TZIC, MT_DEVICE), + imx_map_entry(MX50, SPBA0, MT_DEVICE), + imx_map_entry(MX50, AIPS1, MT_DEVICE), + imx_map_entry(MX50, AIPS2, MT_DEVICE), +}; + +/* + * This function initializes the memory map. It is called during the + * system startup to create static physical to virtual memory mappings + * for the IO modules. + */ +void __init mx50_map_io(void) +{ + mxc_set_cpu_type(MXC_CPU_MX50); + mxc_iomux_v3_init(MX50_IO_ADDRESS(MX50_IOMUXC_BASE_ADDR)); + mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR)); + iotable_init(mx50_io_desc, ARRAY_SIZE(mx50_io_desc)); +} + +int imx50_register_gpios(void); + +void __init mx50_init_irq(void) +{ + tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR)); + imx50_register_gpios(); +} diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index bc3f30db8d9a..457f9f95204b 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2010 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 @@ -23,33 +23,21 @@ /* * Define the MX51 memory map. */ -static struct map_desc mxc_io_desc[] __initdata = { - { - .virtual = MX51_IRAM_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR), - .length = MX51_IRAM_SIZE, - .type = MT_DEVICE - }, { - .virtual = MX51_DEBUG_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR), - .length = MX51_DEBUG_SIZE, - .type = MT_DEVICE - }, { - .virtual = MX51_AIPS1_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR), - .length = MX51_AIPS1_SIZE, - .type = MT_DEVICE - }, { - .virtual = MX51_SPBA0_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR), - .length = MX51_SPBA0_SIZE, - .type = MT_DEVICE - }, { - .virtual = MX51_AIPS2_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR), - .length = MX51_AIPS2_SIZE, - .type = MT_DEVICE - }, +static struct map_desc mx51_io_desc[] __initdata = { + imx_map_entry(MX51, IRAM, MT_DEVICE), + imx_map_entry(MX51, DEBUG, MT_DEVICE), + imx_map_entry(MX51, AIPS1, MT_DEVICE), + imx_map_entry(MX51, SPBA0, MT_DEVICE), + imx_map_entry(MX51, AIPS2, MT_DEVICE), +}; + +/* + * Define the MX53 memory map. + */ +static struct map_desc mx53_io_desc[] __initdata = { + imx_map_entry(MX53, AIPS1, MT_DEVICE), + imx_map_entry(MX53, SPBA0, MT_DEVICE), + imx_map_entry(MX53, AIPS2, MT_DEVICE), }; /* @@ -61,8 +49,16 @@ void __init mx51_map_io(void) { mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); - mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR)); - iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); + mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); + iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc)); +} + +void __init mx53_map_io(void) +{ + mxc_set_cpu_type(MXC_CPU_MX53); + mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR)); + mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG_BASE_ADDR)); + iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc)); } int imx51_register_gpios(void); @@ -72,7 +68,7 @@ void __init mx51_init_irq(void) unsigned long tzic_addr; void __iomem *tzic_virt; - if (mx51_revision() < MX51_CHIP_REV_2_0) + if (mx51_revision() < IMX_CHIP_REVISION_2_0) tzic_addr = MX51_TZIC_BASE_ADDR_TO1; else tzic_addr = MX51_TZIC_BASE_ADDR; @@ -84,3 +80,20 @@ void __init mx51_init_irq(void) tzic_init_irq(tzic_virt); imx51_register_gpios(); } + +int imx53_register_gpios(void); + +void __init mx53_init_irq(void) +{ + unsigned long tzic_addr; + void __iomem *tzic_virt; + + tzic_addr = MX53_TZIC_BASE_ADDR; + + tzic_virt = ioremap(tzic_addr, SZ_16K); + if (!tzic_virt) + panic("unable to map TZIC interrupt controller\n"); + + tzic_init_irq(tzic_virt); + imx53_register_gpios(); +} |