diff options
Diffstat (limited to 'arch/arm/mach-mx5')
44 files changed, 9972 insertions, 1342 deletions
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 5dd3e0fa0b99..c45880ff8521 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -6,6 +6,9 @@ config ARCH_MX51 config ARCH_MX53 bool "MX53" +config ARCH_MX50 + bool + config FORCE_MAX_ZONEORDER int "MAX_ORDER" default "13" @@ -21,7 +24,8 @@ config MX5_MULTI_ARCH bool default y select RUNTIME_PHYS_OFFSET - depends on ARCH_MX51 && ARCH_MX53 + depends on ARCH_MX51 + depends on ARCH_MX50 || ARCH_MX53 config MACH_MX51_3DS bool "Support MX51 3-Stack platform" @@ -44,12 +48,23 @@ config MACH_MX53_EVK Include support for MX53 EVK platform. This includes specific configurations for the board and its peripherals. +config MACH_MX50_ARM2 + bool "Support MX50 Armadillo2 platform" + select ARCH_MX50 + help + Include support for MX50 EVK platform. This includes specific + configurations for the board and its peripherals. + + config MODULE_CCXMX51 bool +config LATE_CPU_CLK_ENABLE + bool config MACH_CCWMX51JS bool "Support for the ConnectCore Wi-i.MX51 module, on the JSK base board" select MODULE_CCXMX51 + select LATE_CPU_CLK_ENABLE help Include support for the Digi ConnectCore Wi-i.MX51 Embedded Module, on the JumpStart Kit base board. This includes specific configurations for the @@ -58,11 +73,64 @@ config MACH_CCWMX51JS config MACH_CCWMX51 bool "Support for the ConnectCore Wi-i.MX51 module" select MODULE_CCXMX51 + select LATE_CPU_CLK_ENABLE help Include support for the Digi ConnectCore Wi-i.MX51 Embedded Module, on a custom board. The machine file should be modified to include support for the interfaces available in that board. +config MACH_CCMX51JS + bool "Support for the ConnectCore i.MX51 module, on the JSK base board" + select MODULE_CCXMX51 + select LATE_CPU_CLK_ENABLE + help + Include support for the Digi ConnectCore i.MX51 Embedded Module, on the + JumpStart Kit base board. This includes specific configurations for the + peripherals on that base board. + +config MACH_CCMX51 + bool "Support for the ConnectCore i.MX51 module" + select MODULE_CCXMX51 + select LATE_CPU_CLK_ENABLE + help + Include support for the Digi ConnectCore i.MX51 Embedded Module, on a + custom board. The machine file should be modified to include support for + the interfaces available in that board. + +choice + prompt "Select development board variant:" + default JSCCWMX51_V2 + +config JSCCWMX51_V1 + bool "ConnectCore for i.MX51 Early Availability Development Board" + depends on MODULE_CCXMX51 + select CCWMX51_DISP0_RGB888 if CCWMX51_DISP0 + help + Select this option if you are using the development board included in + the Early Availability (EA) kit. The Digi part number for this board + revision is 30011032-01. It is printed on the top side of the + development board, close to the connectors of Signal Rail 1. + +config JSCCWMX51_V2 + bool "ConnectCore for i.MX51 JumpStart Kit Development Board" + depends on MODULE_CCXMX51 + select CCWMX51_DISP0_RGB666 if CCWMX51_DISP0 + help + Select this option if you are using the development board included in + Digi JumpStart Kit. The Digi part number for this board revision is + 30011032-03. It is printed on the top side of the development board, + close to the connectors of Signal Rail 1. + +config JSCCWMX51_CUSTOM + bool "Custom ConnectCore for i.MX51 Carrier Board" + depends on MODULE_CCXMX51 + help + Select this option if you are using your own custom-designed carrier + board. + +endchoice + + comment "MX5x Options:" config MXC_SDMA_API @@ -72,6 +140,9 @@ config MXC_SDMA_API This selects the Freescale MXC SDMA API. If unsure, say N. +config MXC_NAND_SWAP_BI + bool + config ARCH_MXC_HAS_NFC_V3 bool "MXC NFC Hardware Version 3" depends on ARCH_MX5 @@ -83,9 +154,10 @@ config ARCH_MXC_HAS_NFC_V3 config ARCH_MXC_HAS_NFC_V3_2 bool "MXC NFC Hardware Version 3.2" depends on ARCH_MXC_HAS_NFC_V3 + select MXC_NAND_SWAP_BI if MODULE_CCXMX51 default y help - This selects the Freescale MXC Nand Flash Controller Hardware Version 3.1 + This selects the Freescale MXC Nand Flash Controller Hardware Version 3.2 If unsure, say N. config SDMA_IRAM @@ -100,50 +172,112 @@ menu "Serial Port Options" config UART1_ENABLED bool "Enable UART1" default y - depends on SERIAL_MXC && MACH_CCWMX51JS + depends on SERIAL_MXC && MODULE_CCXMX51 help Enable the MX51 UART1 interface +choice + prompt "Select the configuration for the UART lines:" + default UART1_2WIRE_ENABLED + depends on UART1_ENABLED + +config UART1_2WIRE_ENABLED + bool "Configure UART1 as 2 wire UART (RX/TX)" + +config UART1_CTS_RTS_ENABLED + bool "Configure UART1 as 4 wire UART (RX/TX/RTS/CTS)" + +config UART1_FULL_UART_ENABLED + bool "Configure UART1 as full UART (RX/TX/RTS/CTS/DCD/DTR/DSR/RI)" +endchoice + +config UART1_IRDA_ENABLED + bool "Enable IRDA mode" + default n + depends on UART1_ENABLED + help + Enable IRDA mode + config UART2_ENABLED bool "Enable UART2" default y - depends on SERIAL_MXC && MACH_CCWMX51JS + depends on SERIAL_MXC && MODULE_CCXMX51 help Enable the MX51 UART2 interface +config UART2_CTS_RTS_ENABLED + bool "Configure RTS/CTS lines for UART2 hardware flow control" + default n + depends on UART2_ENABLED + depends on !USB_EHCI_ARC_H1 + help + Configure the UART2 RTS/CTS lines for hardware flow control operation + +comment "UART2 CTS/RTS is not available on the ConnectCore Wi-i.MX51 JumpStart board if" + depends on USB_EHCI_ARC_H1 +comment "the support for Host1 of the Freescale USB controller is enabled." + depends on USB_EHCI_ARC_H1 + +config UART2_IRDA_ENABLED + bool "Enable IRDA mode" + default n + depends on UART2_ENABLED + help + Enable IRDA mode + +comment "UART3 is not available on the ConnectCore Wi-i.MX51 JumpStart board if UART1" + depends on UART1_FULL_UART_ENABLED +comment "is configured as full UART. This may not be the case in a custom base board." + depends on UART1_FULL_UART_ENABLED + config UART3_ENABLED bool "Enable UART3" default y - depends on SERIAL_MXC && MACH_CCWMX51JS + depends on SERIAL_MXC && MODULE_CCXMX51 && !UART1_FULL_UART_ENABLED help Enable the MX51 UART3 interface + +config UART3_CTS_RTS_ENABLED + bool "Configure RTS/CTS lines for UART3 hardware flow control" + default n + depends on UART3_ENABLED + help + Configure the UART3 RTS/CTS lines for hardware flow control operation + +config UART3_IRDA_ENABLED + bool "Enable IRDA mode" + default n + depends on UART3_ENABLED + help + Enable IRDA mode + endmenu menu "SPI Interface Options" config SPI_MXC_SELECT1 bool "Enable CSPI1" - depends on SPI_MXC && MACH_CCWMX51JS + depends on SPI_MXC && MODULE_CCXMX51 default y help Enable the CSPI1 interface config SPI_MXC_SELECT1_SS1 bool "Enable SS1 line for CSPI1" - depends on SPI_MXC_SELECT1 && MACH_CCWMX51JS + depends on SPI_MXC_SELECT1 && MODULE_CCXMX51 default y help Enable SS1 (slave select 1) line, used on ConnectCore Wi-i.MX51 base board SPI connector config SPI_MXC_SELECT2 bool "Enable CSPI2" - depends on SPI_MXC && MACH_CCWMX51JS + depends on SPI_MXC && MODULE_CCXMX51 default n help Enable the CSPI2 interface config SPI_MXC_SELECT3 bool "Enable CSPI3" - depends on SPI_MXC && MACH_CCWMX51JS + depends on SPI_MXC && MODULE_CCXMX51 default n help Enable the CSPI3 interface @@ -155,6 +289,7 @@ config I2C_MXC_SELECT1 bool "Enable I2C1 module" default y depends on I2C_MXC + depends on !MACH_CCWMX51JS help Enable MX51 I2C1 module. @@ -174,4 +309,106 @@ config I2C_MXC_SELECT3 endmenu -source "arch/arm/mach-mx5/displays/Kconfig"
\ No newline at end of file +menu "SD/MMC Interface options" + +config ESDHCI_MXC_SELECT1 + bool "Enable SDHC 1" + default y + depends on MMC_IMX_ESDHCI + help + Enable the SD Host Controller 1. + +config ESDHCI_MXC_SELECT3 + bool "Enable SDHC 3" + default y + depends on MMC_IMX_ESDHCI + help + Enable the SD Host Controller 3. + +endmenu + +if !FB_MXC_SYNC_PANEL +comment "---Video interface disabled" +endif + +if FB_MXC_SYNC_PANEL +menu "Video Interface(s)" + +choice + prompt "Video color depth" + default CCWMX51_DEFAULT_VIDEO_32BPP + depends on MODULE_CCXMX51 + +config CCWMX51_DEFAULT_VIDEO_32BPP + bool "32 bits per pixel" + +config CCWMX51_DEFAULT_VIDEO_16BPP + bool "16 bits per pixel" +endchoice + +config CCWMX51_DEFAULT_VIDEO_BPP + int + depends on MODULE_CCXMX51 + default 32 if CCWMX51_DEFAULT_VIDEO_32BPP + default 16 if CCWMX51_DEFAULT_VIDEO_16BPP + +config CCWMX51_DISP0 + bool "Enable Display Interface 1 (primary)" + help + This enables the i.MX51 Display Interface 1. + +if CCWMX51_DISP0 +choice + prompt "Display 1 color mode" + +config CCWMX51_DISP0_RGB888 + bool "24bit color mode" + depends on JSCCWMX51_V1 + help + Configure Display 1 in 24bit color mode. + + WARNING: The JumpStart Kit Development Board (30011032-02) is designed + to work in 18bit mode. To work in 24bit mode you need an Early Availability + Kit Development Board (30011032-01) or a custom designed board that + populates all 24 data lines of the video interface. + + IMPORTANT: If Display 1 is configured for 24bit color depth, Display 2 + will not be available. + +config CCWMX51_DISP0_RGB666 + bool "18bit color mode" + depends on JSCCWMX51_V2 + help + Configure Display 1 in 18bit color mode. Use this mode if working + on a JumpStart Kit Development Board. + + WARNING: The Early Availability Development Board (30011032-01) is + designed to work in 24bit mode. To work in 18bit mode you need a + JumpStart Kit Development Board (30011032-02) or a custom designed + board that only populates 18 data lines of the video interface. + +endchoice +endif + +comment "To enable the Display 2 Video interface, disable the FEC (under network drivers)" + depends on FEC || CCWMX51_DISP0_RGB888 +comment "and set 18bit color mode for the Display 1" + depends on FEC || CCWMX51_DISP0_RGB888 + +config CCWMX51_DISP1 + bool "Enable Display Interface 2 (secondary)" + depends on !FEC && !CCWMX51_DISP0_RGB888 + help + This enables the i.MX51 Display Interface 2 (18bit color mode only). + +config CCWMX51_SECOND_TOUCH + bool "Enable support for external touch controller (ADS7843)" + depends on SPI_MXC_SELECT1 + select TOUCHSCREEN_ADS7846 + help + This enables the support for the external touch interface (ADS7843) available on the + High Resolution Display board, connected to the processor through SPI and that can be + used with the secondary display (but also with the primary) + +endmenu +endif diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 683ba5a78dc2..34d8ae473789 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -4,12 +4,17 @@ # Object file lists. +obj-y := system.o iomux.o cpu.o mm.o devices.o serial.o dma.o lpmodes.o pm.o \ +sdram_autogating.o bus_freq.o usb_dr.o usb_h1.o usb_h2.o dummy_gpio.o wfi.o suspend.o early_setup.o -obj-y := system.o iomux.o cpu.o mm.o clock.o devices.o serial.o dma.o lpmodes.o pm.o \ -sdram_autogating.o bus_freq.o usb_dr.o usb_h1.o usb_h2.o dummy_gpio.o wfi.o suspend.o +obj-$(CONFIG_ARCH_MX51) += clock.o +obj-$(CONFIG_ARCH_MX53) += clock.o +obj-$(CONFIG_ARCH_MX50) += clock_mx50.o obj-$(CONFIG_MACH_MX51_3DS) += mx51_3stack.o mx51_3stack_gpio.o mx51_3stack_pmic_mc13892.o obj-$(CONFIG_MACH_MX51_BABBAGE) += mx51_babbage.o mx51_babbage_gpio.o mx51_babbage_pmic_mc13892.o obj-$(CONFIG_MACH_MX53_EVK) += mx53_evk.o mx53_evk_gpio.o mx53_evk_pmic_mc13892.o +obj-$(CONFIG_MACH_MX50_ARM2) += mx50_arm2.o mx50_arm2_gpio.o mx50_arm2_pmic_mc13892.o obj-$(CONFIG_MACH_CCWMX51JS) += devices_ccwmx51.o mx51_ccwmx51js.o mx51_ccwmx51js_gpio.o +obj-$(CONFIG_MACH_CCMX51JS) += devices_ccwmx51.o mx51_ccwmx51js.o mx51_ccwmx51js_gpio.o obj-$(CONFIG_MXC_PMIC_MC13892) += mx51_ccwmx51js_pmic_mc13892.o diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot index 741f60437582..434ef85a32dc 100644 --- a/arch/arm/mach-mx5/Makefile.boot +++ b/arch/arm/mach-mx5/Makefile.boot @@ -4,3 +4,6 @@ initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000 zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000 params_phys-$(CONFIG_ARCH_MX53) := 0x70000100 initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000 + zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000 +params_phys-$(CONFIG_ARCH_MX50) := 0x70000100 +initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000 diff --git a/arch/arm/mach-mx5/board-ccwmx51.h b/arch/arm/mach-mx5/board-ccwmx51.h index 6696c27c5c36..54376d190e82 100644 --- a/arch/arm/mach-mx5/board-ccwmx51.h +++ b/arch/arm/mach-mx5/board-ccwmx51.h @@ -20,8 +20,14 @@ #else #define UART1_ENABLED 0 #endif -#define UART1_MODE MODE_DCE +#if defined CONFIG_UART1_IRDA_ENABLED +#define UART1_IR IRDA +#else #define UART1_IR NO_IRDA +#endif +#define UART1_MODE MODE_DCE +#define UART1_DMA_ENABLED 0 + /* UART 2 configuration */ #if defined CONFIG_UART2_ENABLED @@ -29,8 +35,13 @@ #else #define UART2_ENABLED 0 #endif -#define UART2_MODE MODE_DCE +#if defined CONFIG_UART2_IRDA_ENABLED +#define UART2_IR IRDA +#else #define UART2_IR NO_IRDA +#endif +#define UART2_MODE MODE_DCE +#define UART2_DMA_ENABLED 0 /* UART 3 configuration */ #if defined CONFIG_UART3_ENABLED @@ -38,19 +49,71 @@ #else #define UART3_ENABLED 0 #endif -#define UART3_MODE MODE_DCE +#if defined CONFIG_UART3_IRDA_ENABLED +#define UART3_IR IRDA +#else #define UART3_IR NO_IRDA +#endif +#define UART3_MODE MODE_DCE +#define UART3_DMA_ENABLED 0 /*! * Specifies if the Irda transmit path is inverting */ #define MXC_IRDA_TX_INV 0 -/*! - * Specifies if the Irda receive path is inverting - */ -#define MXC_IRDA_RX_INV 0 #define MXC_LL_UART_PADDR UART1_BASE_ADDR #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) +/* Second touch interface configuration */ +#ifdef CONFIG_CCWMX51_SECOND_TOUCH +#ifdef CONFIG_JSCCWMX51_V1 +/* Settings for the JSCCWMX51 Board RevA, for the DISP0 */ +#elif defined(CONFIG_JSCCWMX51_V2) +/* Settings for the JSCCWMX51 Board RevB, for the DISP0/DISP1 */ +#endif /* CONFIG_JSCCWMX51_VX */ +#endif /* CONFIG_CCWMX51_SECOND_TOUCH */ + +/* AD9389 interrupt */ +#ifdef CONFIG_JSCCWMX51_V1 +#define AD9389_GPIO_IRQ MX51_PIN_GPIO1_4 +#elif defined(CONFIG_JSCCWMX51_V2) +#define AD9389_GPIO_IRQ MX51_PIN_GPIO1_0 +#endif + + +/* Set Base board revision */ +#ifdef CONFIG_JSCCWMX51_V1 +/* Board revision and mach name postfix */ +#define BASE_BOARD_REV 1 +#define BOARD_NAME " on a EAK board" +/* SD1 card detect irq */ +#define CCWMX51_SD1_CD_IRQ IOMUX_TO_IRQ(MX51_PIN_GPIO1_0) +/* Second touch settings */ +#define SECOND_TS_IRQ_PIN MX51_PIN_DI1_D0_CS +#define SECOND_TS_SPI_SS_PIN MX51_PIN_DI1_D1_CS +#elif defined(CONFIG_JSCCWMX51_V2) +/* Board revision */ +#define BASE_BOARD_REV 2 +#define BOARD_NAME " on a JSK board" +/* SD1 card detect irq, not present CD line... */ +#define CCWMX51_SD1_CD_IRQ 0 +/* Second touch settings */ +#define SECOND_TS_IRQ_PIN MX51_PIN_DI1_D0_CS +#define SECOND_TS_SPI_SS_PIN MX51_PIN_CSPI1_RDY +#else +#define BASE_BOARD_REV 0 +#define BOARD_NAME " on an undefined board" +#endif + +/* framebuffer settings */ +#if defined(CONFIG_CCWMX51_DISP1) && defined(CONFIG_CCWMX51_DISP2) +#define FB_MEM_SIZE SZ_32M +#else +#define FB_MEM_SIZE SZ_16M +#endif + +void ccwmx51_2nd_touch_gpio_init(void); +void ccwmx51_init_2nd_touch(void); + #endif /* __ASM_ARCH_MXC_BOARD_CCWMX51_H__ */ diff --git a/arch/arm/mach-mx5/bus_freq.c b/arch/arm/mach-mx5/bus_freq.c index 4ab60ec6386d..4fcaf95e3019 100644 --- a/arch/arm/mach-mx5/bus_freq.c +++ b/arch/arm/mach-mx5/bus_freq.c @@ -33,12 +33,8 @@ #include <mach/sdram_autogating.h> #include "crm_regs.h" -#define LP_NORMAL_CLK 133000000 -#define LP_MED_CLK 83125000 #define LP_APM_CLK 24000000 #define NAND_LP_APM_CLK 12000000 -#define DDR_LOW_FREQ_CLK 133000000 -#define DDR_NORMAL_CLK 200000000 #define AXI_A_NORMAL_CLK 166250000 #define AXI_A_CLK_NORMAL_DIV 4 #define AXI_B_CLK_NORMAL_DIV 5 @@ -46,7 +42,13 @@ #define EMI_SLOW_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV #define NFC_CLK_NORMAL_DIV 4 +static unsigned long lp_normal_rate; +static unsigned long lp_med_rate; +static unsigned long ddr_normal_rate; +static unsigned long ddr_low_rate; + static struct clk *ddr_clk; +static struct clk *pll1_sw_clk; static struct clk *pll2; static struct clk *pll3; static struct clk *main_bus_clk; @@ -80,11 +82,12 @@ static int busfreq_suspended; /* True if bus_frequency is scaled not using DVFS-PER */ int bus_freq_scaling_is_active; -extern int lp_high_freq; -extern int lp_med_freq; +int cpu_wp_nr; +int lp_high_freq; +int lp_med_freq; + extern int dvfs_core_is_active; extern struct cpu_wp *(*get_cpu_wp)(int *wp); -extern int cpu_wp_nr; struct dvfs_wp dvfs_core_setpoint[] = { {33, 8, 33, 10, 10, 0x08}, @@ -92,7 +95,6 @@ struct dvfs_wp dvfs_core_setpoint[] = { {28, 8, 33, 20, 30, 0x08}, {29, 0, 33, 20, 10, 0x08},}; - int set_low_bus_freq(void) { u32 reg; @@ -101,15 +103,20 @@ int set_low_bus_freq(void) return 0; if (bus_freq_scaling_initialized) { + /* can not enter low bus freq, when cpu is in highest freq */ if (clk_get_rate(cpu_clk) != cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) return 0; + /* currently not support on mx53 */ + if (cpu_is_mx53()) + return 0; + stop_dvfs_per(); stop_sdram_autogating(); /*Change the DDR freq to 133Mhz. */ clk_set_rate(ddr_hf_clk, - clk_round_rate(ddr_hf_clk, DDR_LOW_FREQ_CLK)); + clk_round_rate(ddr_hf_clk, ddr_low_rate)); /* Set PLL3 to 133Mhz if no-one is using it. */ if (clk_get_usecount(pll3) == 0) { @@ -162,6 +169,7 @@ int set_high_bus_freq(int high_bus_freq) u32 reg; if (bus_freq_scaling_initialized) { + stop_sdram_autogating(); if (low_bus_freq_mode) { @@ -206,7 +214,8 @@ int set_high_bus_freq(int high_bus_freq) /*Change the DDR freq to 200MHz*/ clk_set_rate(ddr_hf_clk, - clk_round_rate(ddr_hf_clk, DDR_NORMAL_CLK)); + clk_round_rate(ddr_hf_clk, ddr_normal_rate)); + start_dvfs_per(); } if (bus_freq_scaling_is_active) { @@ -218,24 +227,28 @@ int set_high_bus_freq(int high_bus_freq) cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) high_bus_freq = 1; - if (((clk_get_rate(ahb_clk) == LP_MED_CLK) + if (((clk_get_rate(ahb_clk) == lp_med_rate) && lp_high_freq) || high_bus_freq) { /* Set to the high setpoint. */ high_bus_freq_mode = 1; + clk_set_rate(ahb_clk, - clk_round_rate(ahb_clk, LP_NORMAL_CLK)); + clk_round_rate(ahb_clk, lp_normal_rate)); + clk_set_rate(ddr_hf_clk, - clk_round_rate(ddr_hf_clk, DDR_NORMAL_CLK)); + clk_round_rate(ddr_hf_clk, ddr_normal_rate)); } + if (!lp_high_freq && !high_bus_freq) { /* Set to the medium setpoint. */ high_bus_freq_mode = 0; low_bus_freq_mode = 0; + clk_set_rate(ddr_hf_clk, - clk_round_rate(ddr_hf_clk, - DDR_LOW_FREQ_CLK)); + clk_round_rate(ddr_hf_clk, ddr_low_rate)); + clk_set_rate(ahb_clk, - clk_round_rate(ahb_clk, LP_MED_CLK)); + clk_round_rate(ahb_clk, lp_med_rate)); } } start_sdram_autogating(); @@ -288,6 +301,7 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev, clk_set_parent(main_bus_clk, pll2); bus_freq_scaling_is_active = 1; + set_high_bus_freq(0); } else if (strstr(buf, "0") != NULL) { if (bus_freq_scaling_is_active) @@ -325,6 +339,7 @@ static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show, static int __devinit busfreq_probe(struct platform_device *pdev) { int err = 0; + unsigned long pll2_rate, pll1_rate; busfreq_dev = &pdev->dev; @@ -335,12 +350,41 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(main_bus_clk); } + pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); + if (IS_ERR(pll1_sw_clk)) { + printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n", __func__); + return PTR_ERR(pll1_sw_clk); + } + pll2 = clk_get(NULL, "pll2"); if (IS_ERR(pll2)) { printk(KERN_DEBUG "%s: failed to get pll2\n", __func__); return PTR_ERR(pll2); } + pll1_rate = clk_get_rate(pll1_sw_clk); + pll2_rate = clk_get_rate(pll2); + + if (pll2_rate == 665000000) { + /* for mx51 */ + lp_normal_rate = pll2_rate / 5; + lp_med_rate = pll2_rate / 8; + ddr_normal_rate = pll1_rate / 4; /* 200M */ + ddr_low_rate = pll1_rate / 6; /* 133M */ + } else if (pll2_rate == 600000000) { + /* for mx53 evk rev.A */ + lp_normal_rate = pll2_rate / 5; + lp_med_rate = pll2_rate / 8; + ddr_normal_rate = pll2_rate / 2; + ddr_low_rate = pll2_rate / 2; + } else if (pll2_rate == 400000000) { + /* for mx53 evk rev.B */ + lp_normal_rate = pll2_rate / 3; + lp_med_rate = pll2_rate / 5; + ddr_normal_rate = pll2_rate / 1; + ddr_low_rate = pll2_rate / 3; + } + pll3 = clk_get(NULL, "pll3"); if (IS_ERR(pll3)) { printk(KERN_DEBUG "%s: failed to get pll3\n", __func__); @@ -361,7 +405,11 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(axi_b_clk); } - ddr_hf_clk = clk_get(NULL, "ddr_hf_clk"); + if (cpu_is_mx51()) + ddr_hf_clk = clk_get(NULL, "ddr_hf_clk"); + else + ddr_hf_clk = clk_get(NULL, "axi_a_clk"); + if (IS_ERR(ddr_hf_clk)) { printk(KERN_DEBUG "%s: failed to get ddr_hf_clk\n", __func__); diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c index 7c6f614bf97f..09ea14084278 100644 --- a/arch/arm/mach-mx5/clock.c +++ b/arch/arm/mach-mx5/clock.c @@ -42,6 +42,7 @@ static struct clk emi_slow_clk; static struct clk emi_intr_clk[]; static struct clk ddr_clk; static struct clk ipu_clk[]; +static struct clk ldb_di_clk[]; static struct clk axi_a_clk; static struct clk axi_b_clk; static struct clk ddr_hf_clk; @@ -52,16 +53,26 @@ static struct clk vpu_clk[]; static int cpu_curr_wp; static struct cpu_wp *cpu_wp_tbl; -void __iomem *pll1_base; -void __iomem *pll2_base; -void __iomem *pll3_base; -void __iomem *pll4_base; +static void __iomem *pll1_base; +static void __iomem *pll2_base; +static void __iomem *pll3_base; +static void __iomem *pll4_base; + +extern int cpu_wp_nr; +extern int lp_high_freq; +extern int lp_med_freq; +int max_axi_a_clk; +int max_axi_b_clk; -int cpu_wp_nr; -int lp_high_freq; -int lp_med_freq; #define SPIN_DELAY 1000000 /* in nanoseconds */ +#define MAX_AXI_A_CLK_MX51 166250000 +#define MAX_AXI_A_CLK_MX53 400000000 +#define MAX_AXI_B_CLK_MX51 133000000 +#define MAX_AXI_B_CLK_MX53 200000000 +#define MAX_AHB_CLK 133000000 +#define MAX_EMI_SLOW_CLK 133000000 +#define MAX_DDR_HF_RATE 200000000 extern int mxc_jtag_enabled; extern int uart_at_24; @@ -70,8 +81,8 @@ extern int low_bus_freq_mode; static int cpu_clk_set_wp(int wp); extern void propagate_rate(struct clk *tclk); -struct cpu_wp *(*get_cpu_wp)(int *wp); -void (*set_num_cpu_wp)(int num); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +extern void (*set_num_cpu_wp)(int num); static struct clk esdhc3_clk[]; @@ -738,10 +749,18 @@ static unsigned long _clk_axi_a_round_rate(struct clk *clk, u32 div; div = clk->parent->rate / rate; + + /* Make sure rate is not greater than the maximum value for the clock. + * Also prevent a div of 0. + */ + if (div == 0) + div++; + if (clk->parent->rate / div > max_axi_a_clk) + div++; + if (div > 8) div = 8; - else if (div == 0) - div++; + return clk->parent->rate / div; } @@ -771,10 +790,18 @@ static unsigned long _clk_ddr_hf_round_rate(struct clk *clk, u32 div; div = clk->parent->rate / rate; + + /* Make sure rate is not greater than the maximum value for the clock. + * Also prevent a div of 0. + */ + if (div == 0) + div++; + if (clk->parent->rate / div > MAX_DDR_HF_RATE) + div++; + if (div > 8) div = 8; - else if (div == 0) - div++; + return clk->parent->rate / div; } @@ -875,10 +902,18 @@ static unsigned long _clk_axi_b_round_rate(struct clk *clk, u32 div; div = clk->parent->rate / rate; + + /* Make sure rate is not greater than the maximum value for the clock. + * Also prevent a div of 0. + */ + if (div == 0) + div++; + if (clk->parent->rate / div > max_axi_b_clk) + div++; + if (div > 8) div = 8; - else if (div == 0) - div++; + return clk->parent->rate / div; } @@ -945,10 +980,18 @@ static unsigned long _clk_ahb_round_rate(struct clk *clk, u32 div; div = clk->parent->rate / rate; + + /* Make sure rate is not greater than the maximum value for the clock. + * Also prevent a div of 0. + */ + if (div == 0) + div++; + if (clk->parent->rate / div > MAX_AHB_CLK) + div++; + if (div > 8) div = 8; - else if (div == 0) - div++; + return clk->parent->rate / div; } @@ -973,7 +1016,7 @@ static int _clk_max_enable(struct clk *clk) if (cpu_is_mx51()) reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX51; else - reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX53; + reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); return 0; @@ -991,7 +1034,7 @@ static void _clk_max_disable(struct clk *clk) if (cpu_is_mx51()) reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX51; else - reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX53; + reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); } @@ -1078,10 +1121,18 @@ static unsigned long _clk_emi_slow_round_rate(struct clk *clk, u32 div; div = clk->parent->rate / rate; + + /* Make sure rate is not greater than the maximum value for the clock. + * Also prevent a div of 0. + */ + if (div == 0) + div++; + if (clk->parent->rate / div > MAX_EMI_SLOW_CLK) + div++; + if (div > 8) div = 8; - else if (div == 0) - div++; + return clk->parent->rate / div; } @@ -1143,6 +1194,9 @@ static struct clk emi_intr_clk[] = { .disable = _clk_disable_inwait, }, { + /* On MX51 - this clock is name emi_garb_clk, and controls the + * access of ARM to GARB. + */ .name = "emi_intr_clk", .id = 1, .parent = &ahb_clk, @@ -1311,7 +1365,7 @@ static int _clk_sdma_enable(struct clk *clk) if (cpu_is_mx51()) reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51; else - reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX53; + reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); return 0; @@ -1327,7 +1381,7 @@ static void _clk_sdma_disable(struct clk *clk) if (cpu_is_mx51()) reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51; else - reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX53; + reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; __raw_writel(reg, MXC_CCM_CLPCR); } @@ -1357,7 +1411,10 @@ static int _clk_ipu_enable(struct clk *clk) _clk_enable(clk); /* Handshake with IPU when certain clock rates are changed. */ reg = __raw_readl(MXC_CCM_CCDR); - reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; + if (cpu_is_mx51()) + reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; + else + reg &= ~MXC_CCM_CCDR_IPU_HS_MX53_MASK; __raw_writel(reg, MXC_CCM_CCDR); /* Handshake with IPU when LPM is entered as its enabled. */ @@ -1445,6 +1502,8 @@ static int _clk_ipu_di_set_parent(struct clk *clk, struct clk *parent) reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id); } else if ((parent == &tve_clk) && (clk->id == 1)) reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id); + else if ((parent == &ldb_di_clk[clk->id]) && cpu_is_mx53()) + reg |= 5 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id); else /* Assume any other clock is external clock pin */ reg |= 4 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id); __raw_writel(reg, MXC_CCM_CSCMR2); @@ -1498,7 +1557,10 @@ static int _clk_ipu_di_set_rate(struct clk *clk, unsigned long rate) __raw_writel(reg, MXC_CCM_CDCDR); } else if ((clk->parent == &tve_clk) && (clk->id == 1)) clk->rate = rate; /*the rate decided by tve hw actually*/ - else + else if ((clk->parent == &ldb_di_clk[clk->id]) && cpu_is_mx53()) { + clk->rate = clk->parent->rate; + return 0; + } else return -EINVAL; clk->rate = rate; @@ -1511,12 +1573,16 @@ static unsigned long _clk_ipu_di_round_rate(struct clk *clk, { u32 div; - div = clk->parent->rate / rate; - if (div > 8) - div = 8; - else if (div == 0) - div++; - return clk->parent->rate / div; + if ((clk->parent == &ldb_di_clk[clk->id]) && cpu_is_mx53()) + return clk->parent->rate; + else { + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; + } } static struct clk ipu_di_clk[] = { @@ -1550,6 +1616,128 @@ static struct clk ipu_di_clk[] = { }, }; +static int _clk_ldb_di_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR2); + + if ((parent == &pll3_sw_clk)) { + if (clk->id == 0) + reg &= ~(MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL); + else + reg &= ~(MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL); + } else if ((parent == &pll4_sw_clk)) { + if (clk->id == 0) + reg |= MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL; + else + reg |= MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL; + } else { + BUG(); + } + + __raw_writel(reg, MXC_CCM_CSCMR2); + return 0; +} + +static void _clk_ldb_di_recalc(struct clk *clk) +{ + u32 div; + + if (clk->id == 0) + div = __raw_readl(MXC_CCM_CSCMR2) & + MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; + else + div = __raw_readl(MXC_CCM_CSCMR2) & + MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV; + + if (div) + clk->rate = clk->parent->rate / 7; + else + clk->rate = 2 * clk->parent->rate / 7; +} + +static unsigned long _clk_ldb_di_round_rate(struct clk *clk, + unsigned long rate) +{ + if (rate * 7 <= clk->parent->rate) + return clk->parent->rate / 7; + else + return 2 * clk->parent->rate / 7; +} + +static int _clk_ldb_di_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div = 0; + + if (rate * 7 <= clk->parent->rate) { + div = 7; + rate = clk->parent->rate / 7; + } else + rate = 2 * clk->parent->rate / 7; + + reg = __raw_readl(MXC_CCM_CSCMR2); + if (div == 7) + reg |= (clk->id ? MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV : + MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV); + else + reg &= ~(clk->id ? MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV : + MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV); + __raw_writel(reg, MXC_CCM_CSCMR2); + + clk->rate = rate; + return 0; +} + +static int _clk_ldb_di_enable(struct clk *clk) +{ + _clk_enable(clk); + ipu_di_clk[clk->id].set_parent(&ipu_di_clk[clk->id], clk); + ipu_di_clk[clk->id].parent = clk; + ipu_di_clk[clk->id].rate = clk->rate; + ipu_di_clk[clk->id].enable(&ipu_di_clk[clk->id]); + ipu_di_clk[clk->id].usecount++; + return 0; +} + +static void _clk_ldb_di_disable(struct clk *clk) +{ + _clk_disable(clk); + ipu_di_clk[clk->id].disable(&ipu_di_clk[clk->id]); + ipu_di_clk[clk->id].usecount--; +} + +static struct clk ldb_di_clk[] = { + { + .name = "ldb_di0_clk", + .id = 0, + .parent = &pll4_sw_clk, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG14_OFFSET, + .recalc = _clk_ldb_di_recalc, + .set_parent = _clk_ldb_di_set_parent, + .round_rate = _clk_ldb_di_round_rate, + .set_rate = _clk_ldb_di_set_rate, + .enable = _clk_ldb_di_enable, + .disable = _clk_ldb_di_disable, + .flags = RATE_PROPAGATES | AHB_MED_SET_POINT, + }, + { + .name = "ldb_di1_clk", + .id = 1, + .parent = &pll4_sw_clk, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG15_OFFSET, + .recalc = _clk_ldb_di_recalc, + .set_parent = _clk_ldb_di_set_parent, + .round_rate = _clk_ldb_di_round_rate, + .set_rate = _clk_ldb_di_set_rate, + .enable = _clk_ldb_di_enable, + .disable = _clk_ldb_di_disable, + .flags = RATE_PROPAGATES | AHB_MED_SET_POINT, + }, +}; + static int _clk_csi0_set_parent(struct clk *clk, struct clk *parent) { u32 reg, mux; @@ -2060,28 +2248,6 @@ static struct clk uart5_clk[] = { }, }; -static struct clk esai_clk[] = { - { - .name = "esai_clk", - .id = 2, - .parent = &pll3_sw_clk, - .secondary = &esai_clk[1], - .enable_reg = MXC_CCM_CCGR6, - .enable_shift = MXC_CCM_CCGR6_CG9_OFFSET, - .enable = _clk_enable, - .disable = _clk_disable, - }, - { - .name = "esai_ipg_clk", - .id = 2, - .parent = &pll3_sw_clk, - .enable_reg = MXC_CCM_CCGR6, - .enable_shift = MXC_CCM_CCGR6_CG8_OFFSET, - .enable = _clk_enable, - .disable = _clk_disable, - }, -}; - static struct clk gpt_clk[] = { { .name = "gpt_clk", @@ -2311,23 +2477,15 @@ static struct clk cspi2_clk[] = { }, }; -static struct clk cspi3_clk[] = { - { - .name = "cspi_clk", - .id = 2, - .parent = &cspi_main_clk, - .enable_reg = MXC_CCM_CCGR4, - .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET, - .enable = _clk_enable, - .disable = _clk_disable, - .secondary = &cspi3_clk[1], - }, - { - .name = "cspi_ipg_clk", - .id = 2, - .parent = &ipg_clk, - .secondary = &aips_tz2_clk, - }, +static struct clk cspi3_clk = { + .name = "cspi_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &aips_tz2_clk, }; static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent) @@ -2612,6 +2770,83 @@ static struct clk ssi_ext2_clk = { .disable = _clk_disable, }; +static int _clk_esai_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + if (parent == &pll1_sw_clk || parent == &pll2_sw_clk || + parent == &pll3_sw_clk) { + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + NULL); + reg &= ~MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET; + reg &= ~MXC_CCM_CSCMR2_ESAI_POST_SEL_MASK; + reg |= 0 << MXC_CCM_CSCMR2_ESAI_POST_SEL_OFFSET; + /* divider setting */ + } else { + mux = _get_mux(parent, &ssi1_clk[0], &ssi2_clk[0], &ckih_clk, + &ckih2_clk); + reg &= ~MXC_CCM_CSCMR2_ESAI_POST_SEL_MASK; + reg |= (mux + 1) << MXC_CCM_CSCMR2_ESAI_POST_SEL_OFFSET; + /* divider setting */ + } + + __raw_writel(reg, MXC_CCM_CSCMR2); + + /* set podf = 0 */ + reg = __raw_readl(MXC_CCM_CS1CDR); + reg &= ~MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK; + __raw_writel(reg, MXC_CCM_CS1CDR); + + return 0; +} + +static void _clk_esai_recalc(struct clk *clk) +{ + u32 reg, pred, podf; + + reg = __raw_readl(MXC_CCM_CS1CDR); + if (clk->parent == &pll1_sw_clk || clk->parent == &pll2_sw_clk || + clk->parent == &pll3_sw_clk) { + pred = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK) >> + MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (pred * podf); + } else { + podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / podf; + } +} + +static struct clk esai_clk[] = { + { + .name = "esai_clk", + .id = 0, + .parent = &pll3_sw_clk, + .set_parent = _clk_esai_set_parent, + .recalc = _clk_esai_recalc, + .secondary = &esai_clk[1], + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "esai_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + static struct clk iim_clk = { .name = "iim_clk", .parent = &ipg_clk, @@ -3135,51 +3370,63 @@ static struct clk ieee_1588_clk = { .disable = _clk_disable, }; -static struct clk mlb_clk = { +static struct clk mlb_clk[] = { + { .name = "mlb_clk", .parent = &ipg_clk, .enable = _clk_enable, .enable_reg = MXC_CCM_CCGR7, .enable_shift = MXC_CCM_CCGR7_CG2_OFFSET, .disable = _clk_disable, + .secondary = &mlb_clk[1], + }, + { + .name = "mlb_mem_clk", + .parent = &emi_fast_clk, + .secondary = &emi_intr_clk[1], + }, }; static struct clk can1_clk[] = { { - .name = "can1_clk", - .parent = &pll3_sw_clk, - .secondary = &can1_clk[1], + .name = "can_clk", + .id = 0, + .parent = &ipg_clk, .enable = _clk_enable, + .secondary = &can1_clk[1], .enable_reg = MXC_CCM_CCGR6, - .enable_shift = MXC_CCM_CCGR6_CG11_OFFSET, + .enable_shift = MXC_CCM_CCGR6_CG10_OFFSET, .disable = _clk_disable, }, { - .name = "can1_ipg_clk", - .parent = &ipg_clk, + .name = "can_cpi_clk", + .id = 0, + .parent = &lp_apm_clk, .enable = _clk_enable, .enable_reg = MXC_CCM_CCGR6, - .enable_shift = MXC_CCM_CCGR6_CG10_OFFSET, + .enable_shift = MXC_CCM_CCGR6_CG11_OFFSET, .disable = _clk_disable, }, }; static struct clk can2_clk[] = { { - .name = "can2_clk", - .parent = &pll3_sw_clk, - .secondary = &can2_clk[1], + .name = "can_clk", + .id = 1, + .parent = &ipg_clk, .enable = _clk_enable, + .secondary = &can2_clk[1], .enable_reg = MXC_CCM_CCGR4, - .enable_shift = MXC_CCM_CCGR4_CG4_OFFSET, + .enable_shift = MXC_CCM_CCGR4_CG3_OFFSET, .disable = _clk_disable, }, { - .name = "can2_ipg_clk", - .parent = &ipg_clk, + .name = "can_cpi_clk", + .id = 1, + .parent = &lp_apm_clk, .enable = _clk_enable, .enable_reg = MXC_CCM_CCGR4, - .enable_shift = MXC_CCM_CCGR4_CG3_OFFSET, + .enable_shift = MXC_CCM_CCGR4_CG4_OFFSET, .disable = _clk_disable, }, }; @@ -3680,7 +3927,6 @@ static struct clk pgc_clk = { }; /*usb OTG clock */ - static struct clk usb_clk = { .name = "usb_clk", .rate = 60000000, @@ -3716,7 +3962,8 @@ static struct clk ata_clk = { }; static struct clk owire_clk = { - .name = "owire_clk", + /* 1w driver come from upstream and use owire as clock name*/ + .name = "owire", .parent = &ipg_perclk, .enable = _clk_enable, .enable_reg = MXC_CCM_CCGR2, @@ -3796,16 +4043,6 @@ static int _clk_gpu3d_set_parent(struct clk *clk, struct clk *parent) return 0; } -static struct clk gpu3d_clk = { - .name = "gpu3d_clk", - .parent = &axi_a_clk, - .set_parent = _clk_gpu3d_set_parent, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CCGR5, - .enable_shift = MXC_CCM_CCGR5_CG1_OFFSET, - .disable = _clk_disable, - .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, -}; static struct clk garb_clk = { .name = "garb_clk", @@ -3816,13 +4053,16 @@ static struct clk garb_clk = { .disable = _clk_disable, }; -static struct clk emi_garb_clk = { - .name = "emi_garb_clk", +static struct clk gpu3d_clk = { + .name = "gpu3d_clk", .parent = &axi_a_clk, + .set_parent = _clk_gpu3d_set_parent, .enable = _clk_enable, - .enable_reg = MXC_CCM_CCGR6, - .enable_shift = MXC_CCM_CCGR6_CG4_OFFSET, - .disable = _clk_disable_inwait, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG1_OFFSET, + .disable = _clk_disable, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &garb_clk, }; static int _clk_gpu2d_set_parent(struct clk *clk, struct clk *parent) @@ -4008,8 +4248,7 @@ static struct clk *mxc_clks[] = { &cspi1_clk[1], &cspi2_clk[0], &cspi2_clk[1], - &cspi3_clk[0], - &cspi3_clk[1], + &cspi3_clk, &ssi_lp_apm_clk, &ssi1_clk[0], &ssi1_clk[1], @@ -4043,6 +4282,7 @@ static struct clk *mxc_clks[] = { &emi_enfc_clk, &emi_fast_clk, &emi_intr_clk[0], + &emi_intr_clk[1], &spdif_xtal_clk, &spdif0_clk[0], &spdif0_clk[1], @@ -4111,9 +4351,6 @@ static void clk_tree_init(void) pll4_sw_clk.parent = &osc_clk; } - if (cpu_is_mx53()) - tve_clk.parent = &pll4_sw_clk; - /* set emi_slow_clk parent */ emi_slow_clk.parent = &main_bus_clk; reg = __raw_readl(MXC_CCM_CBCDR); @@ -4191,6 +4428,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long esdhc2_clk[0].recalc = _clk_esdhc2_recalc; esdhc2_clk[0].set_rate = _clk_esdhc2_set_rate; + emi_intr_clk[1].name = "emi_garb_clk"; clk_tree_init(); for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) @@ -4209,7 +4447,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long clk_register(&spdif1_clk[0]); clk_register(&spdif1_clk[1]); clk_register(&ddr_hf_clk); - clk_register(&emi_garb_clk); + + max_axi_a_clk = MAX_AXI_A_CLK_MX51; + max_axi_b_clk = MAX_AXI_B_CLK_MX51; /* set DDR clock parent */ reg = 0; @@ -4261,8 +4501,10 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long propagate_rate(&pll1_sw_clk); propagate_rate(&pll2_sw_clk); +#ifndef CONFIG_LATE_CPU_CLK_ENABLE + /* See comment below where cpu_clk is enabled for further information */ clk_enable(&cpu_clk); - +#endif /* Set SDHC parents to be PLL2 */ clk_set_parent(&esdhc1_clk[0], &pll2_sw_clk); clk_set_parent(&esdhc2_clk[0], &pll2_sw_clk); @@ -4396,13 +4638,6 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long if (i > cpu_wp_nr) BUG(); - /*Allow for automatic gating of the EMI internal clock. - * If this is done, emi_intr CCGR bits should be set to 11. - */ - reg = __raw_readl((IO_ADDRESS(M4IF_BASE_ADDR) + 0x8c)); - reg &= ~0x1; - __raw_writel(reg, (IO_ADDRESS(M4IF_BASE_ADDR) + 0x8c)); - clk_set_parent(&arm_axi_clk, &axi_a_clk); clk_set_parent(&ipu_clk[0], &axi_b_clk); @@ -4418,8 +4653,8 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long (0 << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CSCDR1); } else { - /* Move UART to run from PLL1 */ - clk_set_parent(&uart_main_clk, &pll1_sw_clk); + /* Move UART to run from PLL2 */ + clk_set_parent(&uart_main_clk, &pll2_sw_clk); /* Set the UART dividers to divide, * so the UART_CLK is 66.5MHz. @@ -4427,7 +4662,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long reg = __raw_readl(MXC_CCM_CSCDR1); reg &= ~MXC_CCM_CSCDR1_UART_CLK_PODF_MASK; reg &= ~MXC_CCM_CSCDR1_UART_CLK_PRED_MASK; - reg |= (5 << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) | + reg |= (4 << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) | (1 << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CSCDR1); } @@ -4446,6 +4681,15 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long base = ioremap(GPT1_BASE_ADDR, SZ_4K); mxc_timer_init(&gpt_clk[0], base, MXC_INT_GPT); +#ifdef CONFIG_LATE_CPU_CLK_ENABLE + /** + * Late enable of the cpu clock. This is causing a random crash at boot + * time on the ConnectCore Wi-i.MX51. Enabling the cpu clock here seems + * to work around the problem. Must be in order to better understand the + * reason of the problem and the real solution to the problem. + */ + clk_enable(&cpu_clk); +#endif return 0; } @@ -4544,7 +4788,6 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long clk_register(*clkp); clk_register(&pll4_sw_clk); - clk_register(&emi_intr_clk[1]); clk_register(&uart4_clk[0]); clk_register(&uart4_clk[1]); clk_register(&uart5_clk[0]); @@ -4554,7 +4797,21 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long clk_register(&ocram_clk); clk_register(&sata_clk); clk_register(&ieee_1588_clk); - clk_register(&mlb_clk); + clk_register(&mlb_clk[0]); + clk_register(&can1_clk[0]); + clk_register(&can2_clk[0]); + clk_register(&ldb_di_clk[0]); + clk_register(&ldb_di_clk[1]); + /* OSC of 22.5792M or 24.576M for ESAI */ + clk_register(&esai_clk[0]); + clk_set_parent(&esai_clk[0], &ckih_clk); + clk_register(&esai_clk[1]); + + ldb_di_clk[0].parent = ldb_di_clk[1].parent = + tve_clk.parent = &pll4_sw_clk; + + max_axi_a_clk = MAX_AXI_A_CLK_MX53; + max_axi_b_clk = MAX_AXI_B_CLK_MX53; /* set DDR clock parent */ reg = __raw_readl(MXC_CCM_CBCMR) & @@ -4575,6 +4832,8 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long clk_set_parent(&esdhc2_clk[0], &esdhc1_clk[0]); clk_set_parent(&esdhc3_clk[0], &pll2_sw_clk); + clk_set_parent(&ipu_di_clk[0], &pll4_sw_clk); + #if 0 /*Setup the LPM bypass bits */ reg = __raw_readl(MXC_CCM_CLPCR); @@ -4585,13 +4844,6 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long __raw_writel(reg, MXC_CCM_CLPCR); #endif - /* Disable the handshake with HSC block as its not - * initialised right now. - */ - reg = __raw_readl(MXC_CCM_CCDR); - reg |= MXC_CCM_CCDR_EMI_HS_MASK; - __raw_writel(reg, MXC_CCM_CCDR); - /* This will propagate to all children and init all the clock rates */ propagate_rate(&osc_clk); propagate_rate(&ckih_clk); @@ -4605,14 +4857,15 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long clk_enable(&main_bus_clk); + /* Set AXI_B_CLK to be 200MHz */ + clk_set_rate(&axi_b_clk, 200000000); + /* Initialise the parents to be axi_b, parents are set to * axi_a when the clocks are enabled. */ clk_set_parent(&vpu_clk[0], &axi_b_clk); clk_set_parent(&vpu_clk[1], &axi_b_clk); - clk_set_parent(&gpu3d_clk, &axi_a_clk); - clk_set_parent(&gpu2d_clk, &axi_a_clk); /* move cspi to 24MHz */ clk_set_parent(&cspi_main_clk, &lp_apm_clk); @@ -4797,27 +5050,27 @@ static int cpu_clk_set_wp(int wp) __raw_writel(reg, MXC_CCM_CCSR); /* Stop the PLL */ - reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL); reg &= ~MXC_PLL_DP_CTL_UPEN; - __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL); /* PDF and MFI */ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET; - __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_OP); + __raw_writel(reg, pll1_base + MXC_PLL_DP_OP); /* MFD */ - __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_MFD); + __raw_writel(p->mfd, pll1_base + MXC_PLL_DP_MFD); /* MFI */ - __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_MFN); + __raw_writel(p->mfn, pll1_base + MXC_PLL_DP_MFN); - reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL); reg |= MXC_PLL_DP_CTL_UPEN; /* Set the UPEN bits */ - __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL); /* Forcefully restart the PLL */ reg |= MXC_PLL_DP_CTL_RST; - __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL); /* Wait for the PLL to lock */ getnstimeofday(&nstimeofday); @@ -4825,7 +5078,7 @@ static int cpu_clk_set_wp(int wp) getnstimeofday(&curtime); if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY) panic("pll1 relock failed\n"); - stat = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL) & + stat = __raw_readl(pll1_base + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF; } while (!stat); diff --git a/arch/arm/mach-mx5/clock_mx50.c b/arch/arm/mach-mx5/clock_mx50.c new file mode 100644 index 000000000000..6bd7fd3b96aa --- /dev/null +++ b/arch/arm/mach-mx5/clock_mx50.c @@ -0,0 +1,3136 @@ +/* + * 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/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/time.h> +#include <linux/hrtimer.h> +#include <linux/mm.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <asm/io.h> +#include <asm/div64.h> +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/clock.h> +#include <mach/mxc_dvfs.h> +#include <mach/sdram_autogating.h> + +#include "crm_regs.h" + +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 pll4_sw_clk; +static struct clk lp_apm_clk; +static struct clk weim_clk; +static struct clk ddr_clk; +static struct clk axi_a_clk; +static struct clk axi_b_clk; +static struct clk gpu2d_clk; +static int cpu_curr_wp; +static struct cpu_wp *cpu_wp_tbl; + +static void __iomem *pll1_base; +static void __iomem *pll2_base; +static void __iomem *pll3_base; +static void __iomem *pll4_base; + +extern int cpu_wp_nr; +extern int lp_high_freq; +extern int lp_med_freq; + +#define SPIN_DELAY 1000000 /* in nanoseconds */ + +extern int mxc_jtag_enabled; +extern int uart_at_24; +extern int cpufreq_trig_needed; +extern int low_bus_freq_mode; + +static int cpu_clk_set_wp(int wp); +extern void propagate_rate(struct clk *tclk); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +extern void (*set_num_cpu_wp)(int num); + +static struct clk esdhc3_clk[]; + +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) +{ + u32 min_pre, temp_pre, old_err, err; + + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 8) { + min_pre = (div - 1) / 64 + 1; + old_err = 8; + for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { + err = div % temp_pre; + if (err == 0) { + *pre = temp_pre; + break; + } + err = temp_pre - err; + if (err < old_err) { + old_err = err; + *pre = temp_pre; + } + } + *post = (div + *pre - 1) / *pre; + } else if (div < 8) { + *pre = div; + *post = 1; + } +} + +static int _clk_enable(struct clk *clk) +{ + u32 reg; + reg = __raw_readl(clk->enable_reg); + reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq++; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq++; + + return 0; +} + +static int _clk_enable_inrun(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + u32 reg; + reg = __raw_readl(clk->enable_reg); + reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); + + if (clk->flags & AHB_HIGH_SET_POINT) + lp_high_freq--; + else if (clk->flags & AHB_MED_SET_POINT) + lp_med_freq--; +} + +static void _clk_disable_inwait(struct clk *clk) +{ + u32 reg; + reg = __raw_readl(clk->enable_reg); + reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); +} + +static unsigned long _clk_round_rate_div(struct clk *clk, + unsigned long rate, + u32 max_div, + u32 *new_div) +{ + u32 div; + + div = DIV_ROUND_UP(clk->parent->rate, rate); + if (div > max_div) + div = max_div; + else if (div == 0) + div++; + if (new_div != NULL) + *new_div = div; + + return clk->parent->rate / div; +} +/* + * For the 4-to-1 muxed input clock + */ +static inline u32 _get_mux(struct clk *parent, struct clk *m0, + struct clk *m1, struct clk *m2, struct clk *m3) +{ + if (parent == m0) + return 0; + else if (parent == m1) + return 1; + else if (parent == m2) + return 2; + else if (parent == m3) + return 3; + else + BUG(); + + return 0; +} + +/* + * For the 4-to-1 muxed input clock + */ +static inline u32 _get_mux8(struct clk *parent, struct clk *m0, struct clk *m1, + struct clk *m2, struct clk *m3, struct clk *m4, + struct clk *m5, struct clk *m6, struct clk *m7) +{ + if (parent == m0) + return 0; + else if (parent == m1) + return 1; + else if (parent == m2) + return 2; + else if (parent == m3) + return 3; + else if (parent == m4) + return 4; + else if (parent == m5) + return 5; + else if (parent == m6) + return 6; + else if (parent == m7) + return 7; + else + BUG(); + + return 0; +} + +static inline void __iomem *_get_pll_base(struct clk *pll) +{ + if (pll == &pll1_main_clk) + return pll1_base; + else if (pll == &pll2_sw_clk) + return pll2_base; + else if (pll == &pll3_sw_clk) + return pll3_base; + else if (pll == &pll4_sw_clk) + return pll4_base; + else + BUG(); + + return NULL; +} + +static struct clk ckih_clk = { + .name = "ckih", + .flags = RATE_PROPAGATES, +}; + +static struct clk ckih2_clk = { + .name = "ckih2", + .flags = RATE_PROPAGATES, +}; + +static struct clk osc_clk = { + .name = "osc", + .flags = RATE_PROPAGATES, +}; + +static struct clk apll_clk = { + .name = "apll", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd0_clk = { + .name = "pfd0", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd1_clk = { + .name = "pfd1", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd2_clk = { + .name = "pfd2", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd3_clk = { + .name = "pfd3", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd4_clk = { + .name = "pfd4", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd5_clk = { + .name = "pfd5", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd6_clk = { + .name = "pfd6", + .flags = RATE_PROPAGATES, +}; + +static struct clk pfd7_clk = { + .name = "pfd7", + .flags = RATE_PROPAGATES, +}; + +static struct clk ckil_clk = { + .name = "ckil", + .flags = RATE_PROPAGATES, +}; + +static void _clk_pll_recalc(struct clk *clk) +{ + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; + unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; + void __iomem *pllbase; + s64 temp; + + pllbase = _get_pll_base(clk); + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; + dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; + + if (pll_hfsm == 0) { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + } else { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); + } + pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; + mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; + mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; + /* Sign extend to 32-bits */ + if (mfn >= 0x04000000) { + mfn |= 0xFC000000; + mfn_abs = -mfn; + } + + ref_clk = 2 * clk->parent->rate; + if (dbl != 0) + ref_clk *= 2; + + ref_clk /= (pdf + 1); + temp = (u64) ref_clk * mfn_abs; + do_div(temp, mfd + 1); + if (mfn < 0) + temp = -temp; + temp = (ref_clk * mfi) + temp; + + clk->rate = temp; +} + +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, reg1; + void __iomem *pllbase; + struct timespec nstimeofday; + struct timespec curtime; + + long mfi, pdf, mfn, mfd = 999999; + s64 temp64; + unsigned long quad_parent_rate; + unsigned long pll_hfsm, dp_ctl; + + pllbase = _get_pll_base(clk); + + quad_parent_rate = 4*clk->parent->rate; + pdf = mfi = -1; + while (++pdf < 16 && mfi < 5) + mfi = rate * (pdf+1) / quad_parent_rate; + if (mfi > 15) + return -1; + pdf--; + + temp64 = rate*(pdf+1) - quad_parent_rate*mfi; + do_div(temp64, quad_parent_rate/1000000); + mfn = (long)temp64; + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + /* use dpdck0_2 */ + __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); + pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; + if (pll_hfsm == 0) { + reg = mfi<<4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); + } else { + reg = mfi<<4 | pdf; + __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); + __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); + __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); + } + /* If auto restart is disabled, restart the PLL and + * wait for it to lock. + */ + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); + if (reg & MXC_PLL_DP_CTL_UPEN) { + reg = __raw_readl(pllbase + MXC_PLL_DP_CONFIG); + if (!(reg & MXC_PLL_DP_CONFIG_AREN)) { + reg1 = __raw_readl(pllbase + MXC_PLL_DP_CTL); + reg1 |= MXC_PLL_DP_CTL_RST; + __raw_writel(reg1, pllbase + MXC_PLL_DP_CTL); + } + /* Wait for lock */ + getnstimeofday(&nstimeofday); + while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) + & MXC_PLL_DP_CTL_LRF)) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) + panic("pll_set_rate: pll relock failed\n"); + } + } + clk->rate = rate; + return 0; +} + +static int _clk_pll_enable(struct clk *clk) +{ + u32 reg; + void __iomem *pllbase; + struct timespec nstimeofday; + struct timespec curtime; + + pllbase = _get_pll_base(clk); + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); + + /* Wait for lock */ + getnstimeofday(&nstimeofday); + while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF)) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) + panic("pll relock failed\n"); + } + return 0; +} + +static void _clk_pll_disable(struct clk *clk) +{ + u32 reg; + void __iomem *pllbase; + + pllbase = _get_pll_base(clk); + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); +} + +static struct clk pll1_main_clk = { + .name = "pll1_main_clk", + .parent = &osc_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CCSR); + + if (parent == &pll1_main_clk) { + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + /* Set the step_clk parent to be lp_apm, to save power. */ + mux = _get_mux(&lp_apm_clk, &lp_apm_clk, NULL, &pll2_sw_clk, + &pll3_sw_clk); + reg = __raw_readl(MXC_CCM_CCSR); + reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | + (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET); + } else { + if (parent == &lp_apm_clk) { + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + reg = __raw_readl(MXC_CCM_CCSR); + mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk, + &pll3_sw_clk); + reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | + (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET); + } else { + mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk, + &pll3_sw_clk); + reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | + (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CCSR); + reg = __raw_readl(MXC_CCM_CCSR); + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + + } + } + __raw_writel(reg, MXC_CCM_CCSR); + + return 0; +} + +static void _clk_pll1_sw_recalc(struct clk *clk) +{ + u32 reg, div; + div = 1; + reg = __raw_readl(MXC_CCM_CCSR); + + if (clk->parent == &pll2_sw_clk) { + div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >> + MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1; + } else if (clk->parent == &pll3_sw_clk) { + div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >> + MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1; + } + clk->rate = clk->parent->rate / div; +} + +/* pll1 switch clock */ +static struct clk pll1_sw_clk = { + .name = "pll1_sw_clk", + .parent = &pll1_main_clk, + .set_parent = _clk_pll1_sw_set_parent, + .recalc = _clk_pll1_sw_recalc, + .flags = RATE_PROPAGATES, +}; + +static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCSR); + + if (parent == &pll2_sw_clk) { + reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL; + } else { + reg = (reg & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL); + reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL; + } + __raw_writel(reg, MXC_CCM_CCSR); + return 0; +} + +/* same as pll2_main_clk. These two clocks should always be the same */ +static struct clk pll2_sw_clk = { + .name = "pll2", + .parent = &osc_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .set_rate = _clk_pll_set_rate, + .set_parent = _clk_pll2_sw_set_parent, + .flags = RATE_PROPAGATES, +}; + +/* same as pll3_main_clk. These two clocks should always be the same */ +static struct clk pll3_sw_clk = { + .name = "pll3", + .parent = &osc_clk, + .set_rate = _clk_pll_set_rate, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +/* same as pll4_main_clk. These two clocks should always be the same */ +static struct clk pll4_sw_clk = { + .name = "pll4", + .parent = &osc_clk, + .set_rate = _clk_pll_set_rate, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + if (parent == &osc_clk) + reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL; + else if (parent == &apll_clk) + reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL; + else + return -EINVAL; + + __raw_writel(reg, MXC_CCM_CCSR); + + return 0; +} + +static struct clk lp_apm_clk = { + .name = "lp_apm", + .parent = &osc_clk, + .set_parent = _clk_lp_apm_set_parent, + .flags = RATE_PROPAGATES, +}; + +static void _clk_arm_recalc(struct clk *clk) +{ + u32 cacrr, div; + + cacrr = __raw_readl(MXC_CCM_CACRR); + div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +{ + u32 i; + for (i = 0; i < cpu_wp_nr; i++) { + if (rate == cpu_wp_tbl[i].cpu_rate) + break; + } + if (i >= cpu_wp_nr) + return -EINVAL; + cpu_clk_set_wp(i); + + return 0; +} + +static unsigned long _clk_cpu_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 i; + u32 wp; + + for (i = 0; i < cpu_wp_nr; i++) { + if (rate == cpu_wp_tbl[i].cpu_rate) + break; + } + + if (i > cpu_wp_nr) + wp = 0; + + return cpu_wp_tbl[wp].cpu_rate; +} + + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &pll1_sw_clk, + .recalc = _clk_arm_recalc, + .set_rate = _clk_cpu_set_rate, + .round_rate = _clk_cpu_round_rate, +}; + +/* TODO: Need to sync with GPC to determine if DVFS is in place so that + * the DVFS_PODF divider can be applied in CDCR register. + */ +static void _clk_main_bus_recalc(struct clk *clk) +{ + u32 div = 0; + + if (dvfs_per_divider_active() || low_bus_freq_mode) + div = (__raw_readl(MXC_CCM_CDCR) & 0x3); + clk->rate = clk->parent->rate / (div + 1); +} + +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CBCDR) & ~MX50_CCM_CBCDR_PERIPH_CLK_SEL_MASK; + reg |= mux; + __raw_writel(reg, MXC_CCM_CBCDR); + + return 0; +} + +static struct clk main_bus_clk = { + .name = "main_bus_clk", + .parent = &pll2_sw_clk, + .set_parent = _clk_main_bus_set_parent, + .recalc = _clk_main_bus_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_axi_a_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AXI_A_PODF_MASK) >> + MXC_CCM_CBCDR_AXI_A_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_axi_a_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + struct timespec nstimeofday; + struct timespec curtime; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_AXI_A_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); + + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AXI_A_PODF_BUSY) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) + panic("pll _clk_axi_a_set_rate failed\n"); + } + clk->rate = rate; + + return 0; +} + +static unsigned long _clk_axi_a_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + + +static struct clk axi_a_clk = { + .name = "axi_a_clk", + .parent = &main_bus_clk, + .recalc = _clk_axi_a_recalc, + .set_rate = _clk_axi_a_set_rate, + .round_rate = _clk_axi_a_round_rate, + .flags = RATE_PROPAGATES, +}; + +static void _clk_axi_b_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AXI_B_PODF_MASK) >> + MXC_CCM_CBCDR_AXI_B_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_axi_b_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + struct timespec nstimeofday; + struct timespec curtime; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_AXI_B_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); + + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AXI_B_PODF_BUSY) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) + panic("_clk_axi_b_set_rate failed\n"); + } + + clk->rate = rate; + + return 0; +} + +static unsigned long _clk_axi_b_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + + +static struct clk axi_b_clk = { + .name = "axi_b_clk", + .parent = &main_bus_clk, + .recalc = _clk_axi_b_recalc, + .set_rate = _clk_axi_b_set_rate, + .round_rate = _clk_axi_b_round_rate, + .flags = RATE_PROPAGATES, +}; + +static void _clk_ahb_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> + MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + + +static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + struct timespec nstimeofday; + struct timespec curtime; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); + + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) + panic("_clk_ahb_set_rate failed\n"); + } + clk->rate = rate; + + return 0; +} + +static unsigned long _clk_ahb_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &main_bus_clk, + .recalc = _clk_ahb_recalc, + .set_rate = _clk_ahb_set_rate, + .round_rate = _clk_ahb_round_rate, + .flags = RATE_PROPAGATES, +}; + +static int _clk_max_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + + /* Handshake with MAX when LPM is entered. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + + +static void _clk_max_disable(struct clk *clk) +{ + u32 reg; + + _clk_disable_inwait(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; + __raw_writel(reg, MXC_CCM_CLPCR); +} + + +static struct clk ahb_max_clk = { + .name = "max_clk", + .parent = &ahb_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG14_OFFSET, + .enable = _clk_max_enable, + .disable = _clk_max_disable, +}; + +static int _clk_weim_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CBCDR); + if (parent == &ahb_clk) + reg |= MX50_CCM_CBCDR_WEIM_CLK_SEL; + else if (parent == &main_bus_clk) + reg &= ~MX50_CCM_CBCDR_WEIM_CLK_SEL; + else + BUG(); + __raw_writel(reg, MXC_CCM_CBCDR); + + return 0; +} + +static void _clk_weim_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> + MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_weim_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + struct timespec nstimeofday; + struct timespec curtime; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_EMI_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_EMI_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_EMI_PODF_BUSY) { + getnstimeofday(&curtime); + if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY) + panic("_clk_emi_slow_set_rate failed\n"); + } + clk->rate = rate; + + return 0; +} + +static unsigned long _clk_weim_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + + +static struct clk weim_clk = { + .name = "weim_clk", + .parent = &main_bus_clk, + .set_parent = _clk_weim_set_parent, + .recalc = _clk_weim_recalc, + .set_rate = _clk_weim_set_rate, + .round_rate = _clk_weim_round_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG8_OFFSET, + .disable = _clk_disable_inwait, + .flags = RATE_PROPAGATES, +}; + +static struct clk ahbmux1_clk = { + .name = "ahbmux1_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG8_OFFSET, + .disable = _clk_disable_inwait, +}; + +static void _clk_ipg_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> + MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .recalc = _clk_ipg_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_ipg_per_recalc(struct clk *clk) +{ + u32 reg, prediv1, prediv2, podf; + + if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) { + /* the main_bus_clk is the one before the DVFS engine */ + reg = __raw_readl(MXC_CCM_CBCDR); + prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1; + prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1; + podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> + MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv1 * prediv2 * podf); + } else if (clk->parent == &ipg_clk) { + clk->rate = ipg_clk.rate; + } else { + BUG(); + } +} + +static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL); + if (mux == 2) { + reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; + } else { + reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; + if (mux == 0) + reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; + else + reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; + } + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk ipg_perclk = { + .name = "ipg_perclk", + .parent = &lp_apm_clk, + .recalc = _clk_ipg_per_recalc, + .set_parent = _clk_ipg_per_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk ipmux1_clk = { + .name = "ipmux1", + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk ipmux2_clk = { + .name = "ipmux2", + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG0_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static int _clk_ocram_enable(struct clk *clk) +{ + return 0; +} + +static void _clk_ocram_disable(struct clk *clk) +{ +} + +static struct clk ocram_clk = { + .name = "ocram_clk", + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG1_OFFSET, + .enable = _clk_ocram_enable, + .disable = _clk_ocram_disable, +}; + + +static struct clk aips_tz1_clk = { + .name = "aips_tz1_clk", + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable_inwait, +}; + +static struct clk aips_tz2_clk = { + .name = "aips_tz2_clk", + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG13_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable_inwait, +}; + +static struct clk gpc_dvfs_clk = { + .name = "gpc_dvfs_clk", + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static int _clk_sdma_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + + /* Handshake with SDMA when LPM is entered. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static void _clk_sdma_disable(struct clk *clk) +{ + u32 reg; + + _clk_disable(clk); + /* No handshake with SDMA as its not enabled. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + + +static struct clk sdma_clk[] = { + { + .name = "sdma_ahb_clk", + .parent = &ahb_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG15_OFFSET, + .enable = _clk_sdma_enable, + .disable = _clk_sdma_disable, + }, + { + .name = "sdma_ipg_clk", + .parent = &ipg_clk, + }, +}; + +static struct clk spba_clk = { + .name = "spba_clk", + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG0_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static void _clk_uart_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_uart_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk uart_main_clk = { + .name = "uart_main_clk", + .parent = &pll2_sw_clk, + .recalc = _clk_uart_recalc, + .set_parent = _clk_uart_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk uart1_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &uart_main_clk, + .secondary = &uart1_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG4_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +#ifdef UART1_DMA_ENABLE + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +#endif + }, + { + .name = "uart_ipg_clk", + .id = 0, + .parent = &ipg_clk, +#ifdef UART1_DMA_ENABLE + .secondary = &aips_tz1_clk, +#endif + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG3_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart2_clk[] = { + { + .name = "uart_clk", + .id = 1, + .parent = &uart_main_clk, + .secondary = &uart2_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +#ifdef UART2_DMA_ENABLE + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +#endif + }, + { + .name = "uart_ipg_clk", + .id = 1, + .parent = &ipg_clk, +#ifdef UART2_DMA_ENABLE + .secondary = &aips_tz1_clk, +#endif + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG5_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart3_clk[] = { + { + .name = "uart_clk", + .id = 2, + .parent = &uart_main_clk, + .secondary = &uart3_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +#ifdef UART3_DMA_ENABLE + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +#endif + }, + { + .name = "uart_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG7_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart4_clk[] = { + { + .name = "uart_clk", + .id = 3, + .parent = &uart_main_clk, + .secondary = &uart4_clk[1], + .enable_reg = MXC_CCM_CCGR7, + .enable_shift = MXC_CCM_CCGR7_CG5_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +#ifdef UART4_DMA_ENABLE + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +#endif + }, + { + .name = "uart_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR7, + .enable_shift = MXC_CCM_CCGR7_CG4_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart5_clk[] = { + { + .name = "uart_clk", + .id = 4, + .parent = &uart_main_clk, + .secondary = &uart5_clk[1], + .enable_reg = MXC_CCM_CCGR7, + .enable_shift = MXC_CCM_CCGR7_CG7_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +#ifdef UART5_DMA_ENABLE + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +#endif + }, + { + .name = "uart_ipg_clk", + .id = 4, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR7, + .enable_shift = MXC_CCM_CCGR7_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk gpt_clk[] = { + { + .name = "gpt_clk", + .parent = &ipg_perclk, + .id = 0, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &gpt_clk[1], + }, + { + .name = "gpt_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "gpt_32k_clk", + .id = 0, + .parent = &ckil_clk, + }, +}; + +static struct clk pwm1_clk[] = { + { + .name = "pwm", + .parent = &ipg_perclk, + .id = 0, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &pwm1_clk[1], + }, + { + .name = "pwm_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG5_OFFSET, + .enable = _clk_enable_inrun, /*Active only when ARM is running. */ + .disable = _clk_disable, + }, + { + .name = "pwm_32k_clk", + .id = 0, + .parent = &ckil_clk, + }, +}; + +static struct clk pwm2_clk[] = { + { + .name = "pwm", + .parent = &ipg_perclk, + .id = 1, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &pwm2_clk[1], + }, + { + .name = "pwm_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG7_OFFSET, + .enable = _clk_enable_inrun, /*Active only when ARM is running. */ + .disable = _clk_disable, + }, + { + .name = "pwm_32k_clk", + .id = 1, + .parent = &ckil_clk, + }, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &ipg_perclk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "i2c_clk", + .id = 1, + .parent = &ipg_perclk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "i2c_clk", + .id = 2, + .parent = &ipg_perclk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG11_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static void _clk_cspi_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR2); + prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >> + MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >> + MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk cspi_main_clk = { + .name = "cspi_main_clk", + .parent = &pll3_sw_clk, + .recalc = _clk_cspi_recalc, + .set_parent = _clk_cspi_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk cspi1_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &cspi_main_clk, + .secondary = &cspi1_clk[1], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "cspi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG9_OFFSET, + .enable = _clk_enable_inrun, /*Active only when ARM is running. */ + .disable = _clk_disable, + }, +}; + +static struct clk cspi2_clk[] = { + { + .name = "cspi_clk", + .id = 1, + .parent = &cspi_main_clk, + .secondary = &cspi2_clk[1], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "cspi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &aips_tz2_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG11_OFFSET, + .enable = _clk_enable_inrun, /*Active only when ARM is running. */ + .disable = _clk_disable, + }, +}; + +static struct clk cspi3_clk = { + .name = "cspi_clk", + .id = 2, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &aips_tz2_clk, +}; + +static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &ckih_clk, &lp_apm_clk, &ckih2_clk, NULL); + reg = __raw_readl(MXC_CCM_CSCMR1) & + ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi_lp_apm_clk = { + .name = "ssi_lp_apm_clk", + .parent = &ckih_clk, + .set_parent = _clk_ssi_lp_apm_set_parent, +}; + +static void _clk_ssi1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CS1CDR); + prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >> + MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} +static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, + &pll3_sw_clk, &ssi_lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi1_clk[] = { + { + .name = "ssi_clk", + .id = 0, + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi1_set_parent, + .secondary = &ssi1_clk[1], + .recalc = _clk_ssi1_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &ssi1_clk[2], + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_dep_clk", + .id = 0, + .parent = &aips_tz2_clk, + }, +}; + +static void _clk_ssi2_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CS2CDR); + prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >> + MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >> + MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, + &pll3_sw_clk, &ssi_lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi2_clk[] = { + { + .name = "ssi_clk", + .id = 1, + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi2_set_parent, + .secondary = &ssi2_clk[1], + .recalc = _clk_ssi2_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG11_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &ssi2_clk[2], + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_dep_clk", + .id = 1, + .parent = &spba_clk, + }, +}; + +static void _clk_ssi_ext1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + clk->rate = clk->parent->rate; + reg = __raw_readl(MXC_CCM_CSCMR1); + if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) { + reg = __raw_readl(MXC_CCM_CS1CDR); + prediv = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK) >> + MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv * podf); + } +} + +static int _clk_ssi_ext1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div, pre, post; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || div > 512) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + reg = __raw_readl(MXC_CCM_CS1CDR); + reg &= ~(MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK | + MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CS1CDR); + + clk->rate = rate; + + return 0; +} + +static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &ssi1_clk[0]) { + reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL; + } else { + reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &ssi_lp_apm_clk); + reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET); + } + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static unsigned long _clk_ssi_ext1_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 pre, post; + u32 div = clk->parent->rate / rate; + + if (clk->parent->rate % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return clk->parent->rate / (pre * post); +} + +static struct clk ssi_ext1_clk = { + .name = "ssi_ext1_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi_ext1_set_parent, + .set_rate = _clk_ssi_ext1_set_rate, + .round_rate = _clk_ssi_ext1_round_rate, + .recalc = _clk_ssi_ext1_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG14_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static void _clk_ssi_ext2_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + clk->rate = clk->parent->rate; + reg = __raw_readl(MXC_CCM_CSCMR1); + if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) { + reg = __raw_readl(MXC_CCM_CS2CDR); + prediv = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK) >> + MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK) >> + MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv * podf); + } +} + +static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &ssi2_clk[0]) { + reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL; + } else { + reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &ssi_lp_apm_clk); + reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET); + } + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi_ext2_clk = { + .name = "ssi_ext2_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi_ext2_set_parent, + .recalc = _clk_ssi_ext2_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG15_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk tmax2_clk = { + .name = "tmax2_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG1_OFFSET, + .disable = _clk_disable, +}; + +static struct clk usb_ahb_clk = { + .name = "usb_ahb_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG13_OFFSET, + .disable = _clk_disable, +}; + +static struct clk usb_phy_clk[] = { + { + .name = "usb_phy1_clk", + .id = 0, + .parent = &osc_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG5_OFFSET, + .disable = _clk_disable, + }, + { + .name = "usb_phy2_clk", + .id = 1, + .parent = &osc_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG6_OFFSET, + .disable = _clk_disable, + } +}; + +static struct clk esdhc_dep_clks = { + .name = "sd_dep_clk", + .parent = &spba_clk, +}; + +static void _clk_esdhc1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = reg & ~MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + + +static int _clk_esdhc1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + u32 pre, post; + + div = clk->parent->rate / rate; + + if ((clk->parent->rate / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set sdhc1 clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR1) & + ~(MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK | + MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR1); + + clk->rate = rate; + return 0; +} + +static struct clk esdhc1_clk[] = { + { + .name = "esdhc_clk", + .id = 0, + .parent = &pll2_sw_clk, + .set_parent = _clk_esdhc1_set_parent, + .recalc = _clk_esdhc1_recalc, + .set_rate = _clk_esdhc1_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG1_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc1_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &esdhc1_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG0_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax2_clk, + .secondary = &esdhc_dep_clks, + }, + +}; + +static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &esdhc1_clk[0]) + reg &= ~MXC_CCM_CSCMR1_ESDHC2_CLK_SEL; + else if (parent == &esdhc3_clk[0]) + reg |= MXC_CCM_CSCMR1_ESDHC2_CLK_SEL; + else + BUG(); + __raw_writel(reg, MXC_CCM_CSCMR1); + return 0; +} + +static struct clk esdhc2_clk[] = { + { + .name = "esdhc_clk", + .id = 1, + .parent = &esdhc1_clk[0], + .set_parent = _clk_esdhc2_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG3_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc2_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &esdhc2_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG2_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax2_clk, + .secondary = &esdhc_dep_clks, + }, +}; + +static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + mux = _get_mux8(parent, &pll1_sw_clk, &pll2_sw_clk, + &pll3_sw_clk, &lp_apm_clk, &pfd0_clk, + &pfd1_clk, &pfd4_clk, &osc_clk); + reg = reg & ~MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static void _clk_esdhc3_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_esdhc3_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + u32 pre, post; + + div = clk->parent->rate / rate; + + if ((clk->parent->rate / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set sdhc1 clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR1) & + ~(MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK | + MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR1); + + clk->rate = rate; + return 0; +} + + +static struct clk esdhc3_clk[] = { + { + .name = "esdhc_clk", + .id = 2, + .parent = &pll2_sw_clk, + .set_parent = _clk_esdhc3_set_parent, + .recalc = _clk_esdhc3_recalc, + .set_rate = _clk_esdhc3_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG5_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc3_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .secondary = &esdhc3_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG4_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &ahb_max_clk, + .secondary = &esdhc_dep_clks, + }, +}; + +static int _clk_esdhc4_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &esdhc1_clk[0]) + reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; + else if (parent == &esdhc3_clk[0]) + reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; + else + BUG(); + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk esdhc4_clk[] = { + { + .name = "esdhc_clk", + .id = 3, + .parent = &esdhc1_clk[0], + .set_parent = _clk_esdhc4_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG7_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc4_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .secondary = &esdhc4_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG6_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax2_clk, + .secondary = &esdhc_dep_clks, + }, +}; + +static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CLK_DDR); + if (parent == &pfd0_clk) + reg |= MXC_CCM_CLK_DDR_DDR_PFD_SEL; + else if (parent == &pll1_sw_clk) + reg &= ~MXC_CCM_CLK_DDR_DDR_PFD_SEL; + else + return -EINVAL; + return 0; +} + +static void _clk_ddr_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CLK_DDR); + div = (reg & MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK) >> + MXC_CCM_CLK_DDR_DDR_DIV_PLL_OFFSET; + if (div) + clk->rate = clk->parent->rate / div; + else + clk->rate = 0; +} + +static struct clk ddr_clk = { + .name = "ddr_clk", + .parent = &pll1_sw_clk, + .set_parent = _clk_ddr_set_parent, + .recalc = _clk_ddr_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_pgc_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CSCDR1); + div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET; + div = 1 >> div; + clk->rate = clk->parent->rate / div; +} + +static struct clk pgc_clk = { + .name = "pgc_clk", + .parent = &ipg_clk, + .recalc = _clk_pgc_recalc, +}; + +/*usb OTG clock */ + +static struct clk usb_clk = { + .name = "usb_clk", + .rate = 60000000, +}; + +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ckil_clk, + .secondary = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG14_OFFSET, + .disable = _clk_disable, +}; + +static struct clk owire_clk = { + /* 1w driver come from upstream and use owire as clock name*/ + .name = "owire", + .parent = &ipg_perclk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG11_OFFSET, + .disable = _clk_disable, +}; + + +static struct clk fec_clk[] = { + { + .name = "fec_clk", + .parent = &ipg_clk, + .secondary = &fec_clk[1], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG12_OFFSET, + .disable = _clk_disable, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + }, + { + .name = "fec_sec1_clk", + .parent = &tmax2_clk, + .secondary = &fec_clk[2], + }, + { + .name = "fec_sec2_clk", + .parent = &aips_tz2_clk, + }, +}; + +static int _clk_gpu2d_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &weim_clk, &ahb_clk); + reg = (reg & ~MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK) | + (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk gpu2d_clk = { + .name = "gpu2d_clk", + .parent = &axi_a_clk, + .set_parent = _clk_gpu2d_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG7_OFFSET, + .disable = _clk_disable, + .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, +}; + +static struct clk apbh_dma_clk = { + .name = "apbh_dma_clk", + .parent = &pll1_sw_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR7, + .enable_shift = MXC_CCM_CCGR7_CG10_OFFSET, +}; + +static int _clk_display_axi_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + mux = _get_mux(parent, &osc_clk, &pfd2_clk, &pll1_sw_clk, NULL); + reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_MASK) | + (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + + return 0; +} + +static void _clk_display_axi_recalc(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_DISPLAY_AXI); + div &= MXC_CCM_DISPLAY_AXI_DIV_MASK; + if (div == 0) { /* gated off */ + clk->rate = clk->parent->rate; + } else { + clk->rate = clk->parent->rate / div; + } +} + +static unsigned long _clk_display_axi_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 max_div = (2 << 6) - 1; + return _clk_round_rate_div(clk, rate, max_div, NULL); +} + +static int _clk_display_axi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 new_div, max_div; + u32 reg; + + max_div = (2 << 6) - 1; + clk->rate = _clk_round_rate_div(clk, rate, max_div, &new_div); + + reg = __raw_readl(MXC_CCM_DISPLAY_AXI); + reg &= ~MXC_CCM_DISPLAY_AXI_DIV_MASK; + reg |= new_div << MXC_CCM_DISPLAY_AXI_DIV_OFFSET; + __raw_writel(reg, MXC_CCM_DISPLAY_AXI); + +#if 0 + while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_DISPLAY_AXI_BUSY) + ; +#endif + + return 0; +} + +static struct clk display_axi_clk = { + .name = "display_axi", + .parent = &osc_clk, + .set_parent = _clk_display_axi_set_parent, + .recalc = _clk_display_axi_recalc, + .set_rate = _clk_display_axi_set_rate, + .round_rate = _clk_display_axi_round_rate, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_DISPLAY_AXI, + .enable_shift = MXC_CCM_DISPLAY_AXI_CLKGATE_OFFSET, +}; + +/* TODO: check Auto-Slow Mode */ +static struct clk pxp_axi_clk = { + .name = "pxp_axi", + .parent = &display_axi_clk, + .secondary = &apbh_dma_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG9_OFFSET, +}; + +static struct clk elcdif_axi_clk = { + .name = "elcdif_axi", + .parent = &display_axi_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG10_OFFSET, +}; + +static int _clk_elcdif_pix_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + mux = _get_mux(parent, &osc_clk, &pfd6_clk, &pll1_sw_clk, &ckih_clk); + reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_MASK) | + (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + + return 0; +} + +static void _clk_elcdif_pix_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_ELCDIFPIX); + prediv = ((reg & MXC_CCM_ELCDIFPIX_CLK_PRED_MASK) >> + MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_ELCDIFPIX_CLK_PODF_MASK) >> + MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static unsigned long _clk_elcdif_pix_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 max_div = (2 << 12) - 1; + return _clk_round_rate_div(clk, rate, max_div, NULL); +} + +static int _clk_elcdif_pix_set_rate(struct clk *clk, unsigned long rate) +{ + u32 new_div, max_div; + u32 reg; + + max_div = (2 << 12) - 1; + clk->rate = _clk_round_rate_div(clk, rate, max_div, &new_div); + + reg = __raw_readl(MXC_CCM_ELCDIFPIX); + /* Pre-divider set to 1 - only use PODF for clk dividing */ + reg &= ~MXC_CCM_ELCDIFPIX_CLK_PRED_MASK; + reg |= 1 << MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET; + reg &= ~MXC_CCM_ELCDIFPIX_CLK_PODF_MASK; + reg |= new_div << MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_ELCDIFPIX); + + return 0; +} + +static struct clk elcdif_pix_clk = { + .name = "elcdif_pix", + .parent = &osc_clk, + .enable = _clk_enable, + .disable = _clk_disable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG6_OFFSET, + .set_parent = _clk_elcdif_pix_set_parent, + .recalc = _clk_elcdif_pix_recalc, + .round_rate = _clk_elcdif_pix_round_rate, + .set_rate = _clk_elcdif_pix_set_rate, +}; + +static int _clk_epdc_axi_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + mux = _get_mux(parent, &osc_clk, &pfd3_clk, &pll1_sw_clk, NULL); + reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_MASK) | + (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + + return 0; +} + +static void _clk_epdc_axi_recalc(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_EPDC_AXI); + div &= MXC_CCM_EPDC_AXI_DIV_MASK; + if (div == 0) { /* gated off */ + clk->rate = clk->parent->rate; + } else { + clk->rate = clk->parent->rate / div; + } +} + +static unsigned long _clk_epdc_axi_round_rate_div(struct clk *clk, + unsigned long rate, + u32 *new_div) +{ + u32 div, max_div; + + max_div = (2 << 6) - 1; + div = DIV_ROUND_UP(clk->parent->rate, rate); + if (div > max_div) + div = max_div; + else if (div == 0) + div++; + if (new_div != NULL) + *new_div = div; + return clk->parent->rate / div; +} + +static unsigned long _clk_epdc_axi_round_rate(struct clk *clk, + unsigned long rate) +{ + return _clk_epdc_axi_round_rate_div(clk, rate, NULL); +} + +static int _clk_epdc_axi_set_rate(struct clk *clk, unsigned long rate) +{ + u32 new_div; + u32 reg; + + clk->rate = _clk_epdc_axi_round_rate_div(clk, rate, &new_div); + + reg = __raw_readl(MXC_CCM_EPDC_AXI); + reg &= ~MXC_CCM_EPDC_AXI_DIV_MASK; + reg |= new_div << MXC_CCM_EPDC_AXI_DIV_OFFSET; + __raw_writel(reg, MXC_CCM_EPDC_AXI); + + while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_EPDC_AXI_BUSY) + ; + + return 0; +} + +static int _clk_epdc_axi_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCGR6); + reg |= MXC_CCM_CCGR6_CG8_MASK; + __raw_writel(reg, MXC_CCM_CCGR6); + + reg = __raw_readl(MXC_CCM_EPDC_AXI); + reg |= MXC_CCM_EPDC_AXI_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_EPDC_AXI); + + return 0; +} + +static void _clk_epdc_axi_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCGR6); + reg &= ~MXC_CCM_CCGR6_CG8_MASK; + __raw_writel(reg, MXC_CCM_CCGR6); + + reg = __raw_readl(MXC_CCM_EPDC_AXI); + reg &= ~MXC_CCM_EPDC_AXI_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_EPDC_AXI); +} + +/* TODO: check Auto-Slow Mode */ +static struct clk epdc_axi_clk = { + .name = "epdc_axi", + .parent = &apbh_dma_clk, + .set_parent = _clk_epdc_axi_set_parent, + .recalc = _clk_epdc_axi_recalc, + .set_rate = _clk_epdc_axi_set_rate, + .round_rate = _clk_epdc_axi_round_rate, + .enable = _clk_epdc_axi_enable, + .disable = _clk_epdc_axi_disable, +}; + + +static int _clk_epdc_pix_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + mux = _get_mux(parent, &osc_clk, &pfd5_clk, &pll1_sw_clk, &ckih_clk); + reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_MASK) | + (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + + return 0; +} + +static void _clk_epdc_pix_recalc(struct clk *clk) +{ + u32 div; + + div = __raw_readl(MXC_CCM_EPDCPIX); + div &= MXC_CCM_EPDC_PIX_CLK_PODF_MASK; + if (div == 0) { /* gated off */ + clk->rate = clk->parent->rate; + } else { + clk->rate = clk->parent->rate / div; + } +} + +static unsigned long _clk_epdc_pix_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 max_div = (2 << 12) - 1; + return _clk_round_rate_div(clk, rate, max_div, NULL); +} + +static int _clk_epdc_pix_set_rate(struct clk *clk, unsigned long rate) +{ + u32 new_div, max_div; + u32 reg; + + max_div = (2 << 12) - 1; + clk->rate = _clk_round_rate_div(clk, rate, max_div, &new_div); + + reg = __raw_readl(MXC_CCM_EPDCPIX); + /* Pre-divider set to 1 - only use PODF for clk dividing */ + reg &= ~MXC_CCM_EPDC_PIX_CLK_PRED_MASK; + reg |= 1 << MXC_CCM_EPDC_PIX_CLK_PRED_OFFSET; + reg &= ~MXC_CCM_EPDC_PIX_CLK_PODF_MASK; + reg |= new_div << MXC_CCM_EPDC_PIX_CLK_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_EPDCPIX); + + while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_EPDC_PIX_BUSY) + ; + + return 0; +} + +static int _clk_epdc_pix_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCGR6); + reg |= MXC_CCM_CCGR6_CG5_MASK; + __raw_writel(reg, MXC_CCM_CCGR6); + + reg = __raw_readl(MXC_CCM_EPDCPIX); + reg |= MXC_CCM_EPDC_PIX_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_EPDCPIX); + + return 0; +} + +static void _clk_epdc_pix_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCGR6); + reg &= ~MXC_CCM_CCGR6_CG5_MASK; + __raw_writel(reg, MXC_CCM_CCGR6); + + reg = __raw_readl(MXC_CCM_EPDCPIX); + reg &= ~MXC_CCM_EPDC_PIX_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_EPDCPIX); +} + +/* TODO: check Auto-Slow Mode */ +static struct clk epdc_pix_clk = { + .name = "epdc_pix", + .parent = &osc_clk, + .set_parent = _clk_epdc_pix_set_parent, + .recalc = _clk_epdc_pix_recalc, + .set_rate = _clk_epdc_pix_set_rate, + .round_rate = _clk_epdc_pix_round_rate, + .enable = _clk_epdc_pix_enable, + .disable = _clk_epdc_pix_disable, +}; + +static void cko1_recalc(struct clk *clk) +{ + unsigned long rate; + u32 reg; + + reg = __raw_readl(MXC_CCM_CCOSR); + reg &= MX50_CCM_CCOSR_CKO1_DIV_MASK; + reg = reg >> MX50_CCM_CCOSR_CKO1_DIV_OFFSET; + rate = clk->parent->rate; + clk->rate = rate / (reg + 1); +} + +static int cko1_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCOSR); + reg |= MX50_CCM_CCOSR_CKO1_EN; + __raw_writel(reg, MXC_CCM_CCOSR); + return 0; +} + +static void cko1_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CCOSR); + reg &= ~MX50_CCM_CCOSR_CKO1_EN; + __raw_writel(reg, MXC_CCM_CCOSR); +} + +static int cko1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + + div = (clk->parent->rate/rate - 1) & 0x7; + reg = __raw_readl(MXC_CCM_CCOSR); + reg &= ~MX50_CCM_CCOSR_CKO1_DIV_MASK; + reg |= div << MX50_CCM_CCOSR_CKO1_DIV_OFFSET; + __raw_writel(reg, MXC_CCM_CCOSR); + return 0; +} + +static unsigned long cko1_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + div = div < 1 ? 1 : div; + div = div > 8 ? 8 : div; + return clk->parent->rate / div; +} + +static int cko1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 sel, reg, fast; + + if (parent == &cpu_clk) { + sel = 0; + fast = 1; + } else if (parent == &pll1_sw_clk) { + sel = 1; + fast = 1; + } else if (parent == &pll2_sw_clk) { + sel = 2; + fast = 1; + } else if (parent == &pll3_sw_clk) { + sel = 3; + fast = 1; + } else if (parent == &apll_clk) { + sel = 0; + fast = 0; + } else if (parent == &pfd0_clk) { + sel = 1; + fast = 0; + } else if (parent == &pfd1_clk) { + sel = 2; + fast = 0; + } else if (parent == &pfd2_clk) { + sel = 3; + fast = 0; + } else if (parent == &pfd3_clk) { + sel = 4; + fast = 0; + } else if (parent == &pfd4_clk) { + sel = 5; + fast = 0; + } else if (parent == &pfd5_clk) { + sel = 6; + fast = 0; + } else if (parent == &pfd6_clk) { + sel = 7; + fast = 0; + } else if (parent == &weim_clk) { + sel = 10; + fast = 0; + } else if (parent == &ahb_clk) { + sel = 11; + fast = 0; + } else if (parent == &ipg_clk) { + sel = 12; + fast = 0; + } else if (parent == &ipg_perclk) { + sel = 13; + fast = 0; + } else if (parent == &pfd7_clk) { + sel = 15; + fast = 0; + } else + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CCOSR); + reg &= ~MX50_CCM_CCOSR_CKO1_SEL_MASK; + reg |= sel << MX50_CCM_CCOSR_CKO1_SEL_OFFSET; + if (fast) + reg &= ~MX50_CCM_CCOSR_CKO1_SLOW_SEL; + else + reg |= MX50_CCM_CCOSR_CKO1_SLOW_SEL; + __raw_writel(reg, MXC_CCM_CCOSR); + return 0; +} +static struct clk cko1_clk = { + .name = "cko1_clk", + .parent = &pll1_sw_clk, + .recalc = cko1_recalc, + .enable = cko1_enable, + .disable = cko1_disable, + .set_rate = cko1_set_rate, + .round_rate = cko1_round_rate, + .set_parent = cko1_set_parent, +}; + +static struct clk *mxc_clks[] = { + &osc_clk, + &ckih_clk, + &ckih2_clk, + &ckil_clk, + &pll1_main_clk, + &pll1_sw_clk, + &pll2_sw_clk, + &pll3_sw_clk, + &ipmux1_clk, + &ipmux2_clk, + &gpc_dvfs_clk, + &lp_apm_clk, + &cpu_clk, + &main_bus_clk, + &axi_a_clk, + &axi_b_clk, + &ahb_clk, + &ahb_max_clk, + &ipg_clk, + &ipg_perclk, + &ahbmux1_clk, + &aips_tz1_clk, + &aips_tz2_clk, + &sdma_clk[0], + &sdma_clk[1], + &uart_main_clk, + &uart1_clk[0], + &uart1_clk[1], + &uart2_clk[0], + &uart2_clk[1], + &uart3_clk[0], + &uart3_clk[1], + &spba_clk, + &i2c_clk[0], + &i2c_clk[1], + &gpt_clk[0], + &gpt_clk[1], + &gpt_clk[2], + &pwm1_clk[0], + &pwm1_clk[1], + &pwm1_clk[2], + &pwm2_clk[0], + &pwm2_clk[1], + &pwm2_clk[2], + &cspi_main_clk, + &cspi1_clk[0], + &cspi1_clk[1], + &cspi2_clk[0], + &cspi2_clk[1], + &cspi3_clk, + &ssi_lp_apm_clk, + &ssi1_clk[0], + &ssi1_clk[1], + &ssi1_clk[2], + &ssi2_clk[0], + &ssi2_clk[1], + &ssi2_clk[2], + &ssi_ext1_clk, + &ssi_ext2_clk, + &tmax2_clk, + &usb_ahb_clk, + &usb_phy_clk[0], + &usb_clk, + &esdhc1_clk[0], + &esdhc1_clk[1], + &esdhc2_clk[0], + &esdhc2_clk[1], + &esdhc3_clk[0], + &esdhc3_clk[1], + &esdhc4_clk[0], + &esdhc4_clk[1], + &esdhc_dep_clks, + &weim_clk, + &ddr_clk, + &pgc_clk, + &rtc_clk, + &owire_clk, + &fec_clk[0], + &fec_clk[1], + &fec_clk[2], + &gpu2d_clk, + &cko1_clk, + &display_axi_clk, + &pxp_axi_clk, + &elcdif_axi_clk, + &epdc_axi_clk, + &epdc_pix_clk, + &elcdif_pix_clk, +}; + +static void clk_tree_init(void) +{ + u32 reg; + + ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk); + + /* + *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at + * 8MHz, its derived from lp_apm. + */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK; + reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK; + reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK; + reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + /* set pll1_main_clk parent */ + pll1_main_clk.parent = &osc_clk; + + /* set pll2_sw_clk parent */ + pll2_sw_clk.parent = &osc_clk; + + /* set pll3_clk parent */ + pll3_sw_clk.parent = &osc_clk; + + /* set weim_clk parent */ + weim_clk.parent = &main_bus_clk; + reg = __raw_readl(MXC_CCM_CBCDR); + if ((reg & MX50_CCM_CBCDR_WEIM_CLK_SEL) != 0) + weim_clk.parent = &ahb_clk; + + /* set ipg_perclk parent */ + ipg_perclk.parent = &lp_apm_clk; + reg = __raw_readl(MXC_CCM_CBCMR); + if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) { + ipg_perclk.parent = &ipg_clk; + } else { + if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0) + ipg_perclk.parent = &main_bus_clk; + } +} + +int __init mx50_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1) +{ + __iomem void *base; + struct clk **clkp; + int i = 0, j = 0, reg; + int wp_cnt = 0; + + pll1_base = ioremap(MX53_BASE_ADDR(PLL1_BASE_ADDR), SZ_4K); + pll2_base = ioremap(MX53_BASE_ADDR(PLL2_BASE_ADDR), SZ_4K); + pll3_base = ioremap(MX53_BASE_ADDR(PLL3_BASE_ADDR), SZ_4K); + + /* Turn off all possible clocks */ + if (mxc_jtag_enabled) { + __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET | + 1 << MXC_CCM_CCGR0_CG2_OFFSET | + 3 << MXC_CCM_CCGR0_CG3_OFFSET | + 3 << MXC_CCM_CCGR0_CG4_OFFSET | + 3 << MXC_CCM_CCGR0_CG8_OFFSET | + 1 << MXC_CCM_CCGR0_CG12_OFFSET | + 1 << MXC_CCM_CCGR0_CG13_OFFSET | + 1 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0); + } else { + __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET | + 3 << MXC_CCM_CCGR0_CG3_OFFSET | + 3 << MXC_CCM_CCGR0_CG8_OFFSET | + 1 << MXC_CCM_CCGR0_CG12_OFFSET | + 1 << MXC_CCM_CCGR0_CG13_OFFSET | + 3 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0); + } + + __raw_writel(0, MXC_CCM_CCGR1); + __raw_writel(0, MXC_CCM_CCGR2); + __raw_writel(0, MXC_CCM_CCGR3); + __raw_writel(0, MXC_CCM_CCGR4); + + __raw_writel(1 << MXC_CCM_CCGR5_CG6_OFFSET | + 1 << MXC_CCM_CCGR5_CG8_OFFSET | + 3 << MXC_CCM_CCGR5_CG9_OFFSET, MXC_CCM_CCGR5); + + __raw_writel(3 << MXC_CCM_CCGR6_CG0_OFFSET | + 3 << MXC_CCM_CCGR6_CG1_OFFSET | + 3 << MXC_CCM_CCGR6_CG4_OFFSET | + 3 << MXC_CCM_CCGR6_CG8_OFFSET | + 3 << MXC_CCM_CCGR6_CG9_OFFSET | + 3 << MXC_CCM_CCGR6_CG12_OFFSET | + 3 << MXC_CCM_CCGR6_CG13_OFFSET , MXC_CCM_CCGR6); + + __raw_writel(0, MXC_CCM_CCGR7); + + ckil_clk.rate = ckil; + osc_clk.rate = osc; + ckih_clk.rate = ckih1; + + usb_phy_clk[0].enable_reg = MXC_CCM_CCGR4; + usb_phy_clk[0].enable_shift = MXC_CCM_CCGR4_CG5_OFFSET; + + clk_tree_init(); + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); + + clk_register(&uart4_clk[0]); + clk_register(&uart4_clk[1]); + clk_register(&uart5_clk[0]); + clk_register(&uart5_clk[1]); + clk_register(&i2c_clk[2]); + clk_register(&usb_phy_clk[1]); + clk_register(&ocram_clk); + + /* set DDR clock parent */ + reg = __raw_readl(MXC_CCM_CLK_DDR) & + MXC_CCM_CLK_DDR_DDR_PFD_SEL; + if (reg) + clk_set_parent(&ddr_clk, &pfd0_clk); + else + clk_set_parent(&ddr_clk, &pll1_sw_clk); + + clk_set_parent(&esdhc1_clk[0], &pll2_sw_clk); + clk_set_parent(&esdhc1_clk[2], &tmax2_clk); + clk_set_parent(&esdhc2_clk[0], &esdhc1_clk[0]); + clk_set_parent(&esdhc3_clk[0], &pll2_sw_clk); + + clk_register(&apbh_dma_clk); + + clk_set_parent(&epdc_axi_clk, &pll1_sw_clk); + /* Set EPDC AXI to 200MHz */ + /* + clk_set_rate(&epdc_axi_clk, 200000000); + */ + __raw_writel(0xC0000008, MXC_CCM_EPDC_AXI); + clk_set_parent(&epdc_pix_clk, &pll1_sw_clk); + + reg = __raw_readl(MXC_CCM_ELCDIFPIX); + reg &= ~MXC_CCM_ELCDIFPIX_CLKGATE_MASK; + reg = 0x3 << MXC_CCM_ELCDIFPIX_CLKGATE_OFFSET; + __raw_writel(reg, MXC_CCM_ELCDIFPIX); + clk_set_parent(&elcdif_pix_clk, &pll1_sw_clk); + + /* This will propagate to all children and init all the clock rates */ + propagate_rate(&osc_clk); + propagate_rate(&ckih_clk); + propagate_rate(&ckil_clk); + propagate_rate(&pll1_sw_clk); + propagate_rate(&pll2_sw_clk); + propagate_rate(&pll3_sw_clk); + + clk_enable(&cpu_clk); + + clk_enable(&main_bus_clk); + + clk_enable(&apbh_dma_clk); + + /* Initialise the parents to be axi_b, parents are set to + * axi_a when the clocks are enabled. + */ + + clk_set_parent(&gpu2d_clk, &axi_a_clk); + + /* move cspi to 24MHz */ + clk_set_parent(&cspi_main_clk, &lp_apm_clk); + clk_set_rate(&cspi_main_clk, 12000000); + + /* set DISPLAY_AXI to 200Mhz */ + clk_set_parent(&display_axi_clk, &pll1_sw_clk); + clk_set_rate(&display_axi_clk, 200000000); + + /* Move SSI clocks to SSI_LP_APM clock */ + clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk); + + clk_set_parent(&ssi1_clk[0], &ssi_lp_apm_clk); + /* set the SSI dividers to divide by 2 */ + reg = __raw_readl(MXC_CCM_CS1CDR); + reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK; + reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK; + reg |= 1 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CS1CDR); + + clk_set_parent(&ssi2_clk[0], &ssi_lp_apm_clk); + reg = __raw_readl(MXC_CCM_CS2CDR); + reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK; + reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK; + reg |= 1 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CS2CDR); + + /* Change the SSI_EXT1_CLK to be sourced from PLL2 for camera */ + clk_disable(&ssi_ext1_clk); + clk_set_parent(&ssi_ext1_clk, &pll2_sw_clk); + clk_set_rate(&ssi_ext1_clk, 24000000); + clk_enable(&ssi_ext1_clk); + clk_set_parent(&ssi_ext2_clk, &ssi2_clk[0]); + + /* move usb_phy_clk to 24MHz */ + clk_set_parent(&usb_phy_clk[0], &osc_clk); + clk_set_parent(&usb_phy_clk[1], &osc_clk); + + /* set SDHC root clock as 200MHZ*/ + clk_set_rate(&esdhc1_clk[0], 200000000); + clk_set_rate(&esdhc3_clk[0], 200000000); + + /* Set the current working point. */ + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + /* Update the cpu working point table based on the PLL1 freq + * at boot time + */ + if (pll1_main_clk.rate <= cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) + wp_cnt = 1; + else if (pll1_main_clk.rate <= cpu_wp_tbl[1].cpu_rate && + pll1_main_clk.rate > cpu_wp_tbl[2].cpu_rate) + wp_cnt = cpu_wp_nr - 1; + else + wp_cnt = cpu_wp_nr; + + cpu_wp_tbl[0].cpu_rate = pll1_main_clk.rate; + + if (wp_cnt == 1) { + cpu_wp_tbl[0] = cpu_wp_tbl[cpu_wp_nr - 1]; + memset(&cpu_wp_tbl[cpu_wp_nr - 1], 0, sizeof(struct cpu_wp)); + memset(&cpu_wp_tbl[cpu_wp_nr - 2], 0, sizeof(struct cpu_wp)); + } else if (wp_cnt < cpu_wp_nr) { + for (i = 0; i < wp_cnt; i++) + cpu_wp_tbl[i] = cpu_wp_tbl[i+1]; + memset(&cpu_wp_tbl[i], 0, sizeof(struct cpu_wp)); + } + + if (wp_cnt < cpu_wp_nr) { + set_num_cpu_wp(wp_cnt); + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + } + + + for (j = 0; j < cpu_wp_nr; j++) { + /* Change the CPU podf divider based on the boot up + * pll1 rate. + */ + cpu_wp_tbl[j].cpu_podf = max( + (int)((pll1_main_clk.rate / cpu_wp_tbl[j].cpu_rate) + - 1), 0); + if (pll1_main_clk.rate/(cpu_wp_tbl[j].cpu_podf + 1) > + cpu_wp_tbl[j].cpu_rate) { + cpu_wp_tbl[j].cpu_podf++; + cpu_wp_tbl[j].cpu_rate = + pll1_main_clk.rate/ + (1000 * (cpu_wp_tbl[j].cpu_podf + 1)); + cpu_wp_tbl[j].cpu_rate *= 1000; + } + if (pll1_main_clk.rate/(cpu_wp_tbl[j].cpu_podf + 1) < + cpu_wp_tbl[j].cpu_rate) { + cpu_wp_tbl[j].cpu_rate = pll1_main_clk.rate; + } + cpu_wp_tbl[j].pll_rate = pll1_main_clk.rate; + } + /* Set the current working point. */ + for (i = 0; i < cpu_wp_nr; i++) { + if (clk_get_rate(&cpu_clk) == cpu_wp_tbl[i].cpu_rate) { + cpu_curr_wp = i; + break; + } + } + if (i > cpu_wp_nr) + BUG(); + + propagate_rate(&osc_clk); + propagate_rate(&pll1_sw_clk); + propagate_rate(&pll2_sw_clk); + propagate_rate(&pll3_sw_clk); + + clk_set_parent(&uart_main_clk, &lp_apm_clk); + clk_set_parent(&gpu2d_clk, &axi_b_clk); + + clk_set_parent(&weim_clk, &ahb_clk); + clk_set_rate(&weim_clk, clk_round_rate(&weim_clk, 130000000)); + + base = ioremap(MX53_BASE_ADDR(GPT1_BASE_ADDR), SZ_4K); + mxc_timer_init(&gpt_clk[0], base, MXC_INT_GPT); + return 0; +} + +/*! + * Setup cpu clock based on working point. + * @param wp cpu freq working point + * @return 0 on success or error code on failure. + */ +static int cpu_clk_set_wp(int wp) +{ + struct cpu_wp *p; + u32 reg; + + if (wp == cpu_curr_wp) + return 0; + + p = &cpu_wp_tbl[wp]; + + /* + * leave the PLL1 freq unchanged. + */ + reg = __raw_readl(MXC_CCM_CACRR); + reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK; + reg |= cpu_wp_tbl[wp].cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CACRR); + cpu_curr_wp = wp; + cpu_clk.rate = cpu_wp_tbl[wp].cpu_rate; + +#if defined(CONFIG_CPU_FREQ) + cpufreq_trig_needed = 1; +#endif + return 0; +} diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index 692d258a4a0c..5abba44d25ad 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -28,11 +28,23 @@ #include <linux/clk.h> #include <mach/common.h> #include <mach/hardware.h> -#include "crm_regs.h" + +#define CORTEXA8_PLAT_AMC 0x18 +#define SRPG_NEON_PUPSCR 0x284 +#define SRPG_NEON_PDNSCR 0x288 +#define SRPG_ARM_PUPSCR 0x2A4 +#define SRPG_ARM_PDNSCR 0x2A8 +#define SRPG_EMPGC0_PUPSCR 0x2E4 +#define SRPG_EMPGC0_PDNSCR 0x2E8 +#define SRPG_EMPGC1_PUPSCR 0x304 +#define SRPG_EMPGC1_PDNSCR 0x308 void __iomem *arm_plat_base; void __iomem *gpc_base; +struct cpu_wp *(*get_cpu_wp)(int *wp); +void (*set_num_cpu_wp)(int num); + static void __init mipi_hsc_disable(void) { void __iomem *reg_hsc_mcd = ioremap(MIPI_HSC_BASE_ADDR, SZ_4K); @@ -54,7 +66,8 @@ static void __init mipi_hsc_disable(void) if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) { temp = __raw_readl(reg_hsc_mxt_conf); - __raw_writel(temp | 0x10000, reg_hsc_mxt_conf); + __raw_writel(0xf003008b, reg_hsc_mxt_conf); + /* Previous value of reg_hsc_mxt_conf was 0xf00100ff */ } clk_disable(clk); @@ -102,6 +115,7 @@ static int __init post_cpu_init(void) { void __iomem *base; unsigned int reg; + struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk"); int iram_size = IRAM_SIZE; if (cpu_is_mx51()) { @@ -116,11 +130,28 @@ static int __init post_cpu_init(void) } gpc_base = ioremap(MX53_BASE_ADDR(GPC_BASE_ADDR), SZ_4K); + clk_enable(gpcclk); + + /* Setup the number of clock cycles to wait for SRPG + * power up and power down requests. + */ + __raw_writel(0x010F0201, gpc_base + SRPG_ARM_PUPSCR); + __raw_writel(0x010F0201, gpc_base + SRPG_NEON_PUPSCR); + __raw_writel(0x00000008, gpc_base + SRPG_EMPGC0_PUPSCR); + __raw_writel(0x00000008, gpc_base + SRPG_EMPGC1_PUPSCR); + + __raw_writel(0x01010101, gpc_base + SRPG_ARM_PDNSCR); + __raw_writel(0x01010101, gpc_base + SRPG_NEON_PDNSCR); + __raw_writel(0x00000018, gpc_base + SRPG_EMPGC0_PDNSCR); + __raw_writel(0x00000018, gpc_base + SRPG_EMPGC1_PDNSCR); + + clk_disable(gpcclk); + clk_put(gpcclk); /* Set ALP bits to 000. Set ALP_EN bit in Arm Memory Controller reg. */ arm_plat_base = ioremap(MX53_BASE_ADDR(ARM_BASE_ADDR), SZ_4K); reg = 0x8; - __raw_writel(reg, MXC_CORTEXA8_PLAT_AMC); + __raw_writel(reg, arm_plat_base + CORTEXA8_PLAT_AMC); base = ioremap(MX53_BASE_ADDR(AIPS1_BASE_ADDR), SZ_4K); __raw_writel(0x0, base + 0x40); @@ -140,14 +171,16 @@ static int __init post_cpu_init(void) __raw_writel(reg, base + 0x50); iounmap(base); - /*Allow for automatic gating of the EMI internal clock. - * If this is done, emi_intr CCGR bits should be set to 11. - */ - base = ioremap(MX53_BASE_ADDR(M4IF_BASE_ADDR), SZ_4K); - reg = __raw_readl(base + 0x8c); - reg &= ~0x1; - __raw_writel(reg, base + 0x8c); - iounmap(base); + if (cpu_is_mx51() || cpu_is_mx53()) { + /*Allow for automatic gating of the EMI internal clock. + * If this is done, emi_intr CCGR bits should be set to 11. + */ + base = ioremap(MX53_BASE_ADDR(M4IF_BASE_ADDR), SZ_4K); + reg = __raw_readl(base + 0x8c); + reg &= ~0x1; + __raw_writel(reg, base + 0x8c); + iounmap(base); + } return 0; } diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h index e53f55d258eb..a1444786b72e 100644 --- a/arch/arm/mach-mx5/crm_regs.h +++ b/arch/arm/mach-mx5/crm_regs.h @@ -13,17 +13,7 @@ #ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__ #define __ARCH_ARM_MACH_MX51_CRM_REGS_H__ -extern void __iomem *ccm_base; -extern void __iomem *pll1_base; -extern void __iomem *pll2_base; -extern void __iomem *pll3_base; -extern void __iomem *pll4_base; - #define MXC_CCM_BASE (IO_ADDRESS(CCM_BASE_ADDR)) -#define MXC_DPLL1_BASE (pll1_base) -#define MXC_DPLL2_BASE (pll2_base) -#define MXC_DPLL3_BASE (pll3_base) -#define MXC_DPLL4_BASE (pll4_base) /* PLL Register Offsets */ #define MXC_PLL_DP_CTL 0x00 @@ -116,6 +106,17 @@ extern void __iomem *pll4_base; #define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80) #define MXC_CCM_CCGR7 (MXC_CCM_BASE + 0x84) #define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x88) +#define MXC_CCM_CSR2 (MXC_CCM_BASE + 0x8C) +#define MXC_CCM_CLKSEQ_BYPASS (MXC_CCM_BASE + 0x90) +#define MXC_CCM_CLK_SYS (MXC_CCM_BASE + 0x94) +#define MXC_CCM_CLK_DDR (MXC_CCM_BASE + 0x98) +#define MXC_CCM_ELCDIFPIX (MXC_CCM_BASE + 0x9C) +#define MXC_CCM_EPDCPIX (MXC_CCM_BASE + 0xA0) +#define MXC_CCM_DISPLAY_AXI (MXC_CCM_BASE + 0xA4) +#define MXC_CCM_EPDC_AXI (MXC_CCM_BASE + 0xA8) +#define MXC_CCM_GPMI (MXC_CCM_BASE + 0xAC) +#define MXC_CCM_BCH (MXC_CCM_BASE + 0xB0) +#define MXC_CCM_MSHC_XMSCKI (MXC_CCM_BASE + 0xB4) /* Define the bits in register CCR */ #define MXC_CCM_CCR_COSC_EN (1 << 12) @@ -149,8 +150,11 @@ extern void __iomem *pll4_base; #define MXC_CCM_CSR_REF_EN_B (1 << 0) /* Define the bits in register CCSR */ -#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9) -#define MXC_CCM_CCSR_LP_APM_SEL_MX53 (0x1 << 10) +#define MXC_CCM_CCSR_PLL3_PFD_EN (0x1 << 13) +#define MXC_CCM_CCSR_PLL2_PFD_EN (0x1 << 12) +#define MXC_CCM_CCSR_PLL1_PFD_EN (0x1 << 11) +#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 10) +#define MXC_CCM_CCSR_LP_APM_SE_MX51L (0x1 << 9) #define MXC_CCM_CCSR_PLL4_SW_CLK_SEL (1 << 9) #define MXC_CCM_CCSR_STEP_SEL_OFFSET (7) #define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7) @@ -167,8 +171,11 @@ extern void __iomem *pll4_base; #define MXC_CCM_CACRR_ARM_PODF_MASK (0x7) /* Define the bits in register CBCDR */ +#define MX50_CCM_CBCDR_WEIM_CLK_SEL (0x1 << 27) #define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26) #define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) +#define MX50_CCM_CBCDR_PERIPH_CLK_SEL_OFFSET (25) +#define MX50_CCM_CBCDR_PERIPH_CLK_SEL_MASK (0x3 << 25) #define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET (30) #define MXC_CCM_CBCDR_DDR_HF_SEL (0x1 << 30) #define MXC_CCM_CBCDR_DDR_PODF_OFFSET (27) @@ -209,6 +216,8 @@ extern void __iomem *pll4_base; #define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4) #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (14) #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 14) +#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_OFFSET (2) +#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_MASK (0x3 << 2) #define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1) #define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0) @@ -228,6 +237,10 @@ extern void __iomem *pll4_base; #define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MX51 (0x1 << 19) #define MXC_CCM_CSCMR1_ESDHC2_CLK_SEL (0x1 << 19) #define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18) +#define MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET (21) +#define MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_MASK (0x3 << 21) +#define MX50_CCM_CSCMR1_ESDHC2_CLK_SEL (0x1 << 20) +#define MX50_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 19) #define MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET (16) #define MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK (0x3 << 16) #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14) @@ -279,11 +292,11 @@ extern void __iomem *pll4_base; #define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9) #define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6) #define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6) -/* MX51 */ -#define MXC_CCM_CSCMR2_LBD_DI1_IPU_DIV (0x1 << 11) -#define MXC_CCM_CSCMR2_LBD_DI0_IPU_DIV (0x1 << 10) -#define MXC_CCM_CSCMR2_LBD_DI1_CLK_SEL (0x1 << 9) -#define MXC_CCM_CSCMR2_LBD_DI0_CLK_SEL (0x1 << 8) +/* MX53 */ +#define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11) +#define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10) +#define MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL (0x1 << 9) +#define MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL (0x1 << 8) #define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET (6) #define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK (0x3 << 6) #define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5) @@ -439,6 +452,9 @@ extern void __iomem *pll4_base; #define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0) /* Define the bits in register CDCR */ +#define MX50_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ_STATUS (0x1 << 7) +#define MX50_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ (0x1 << 6) +#define MX50_CCM_CDCR_SW_DVFS_EN (0x1 << 5) #define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2) #define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0) #define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3) @@ -453,9 +469,10 @@ extern void __iomem *pll4_base; #define MXC_CCM_CLPCR_BYPASS_CAN2_LPM_HS (0x1 << 27) #define MXC_CCM_CLPCR_BYPASS_CAN1_LPM_HS (0x1 << 27) #define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS_MX53 (0x1 << 26) -#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX53 (0x1 << 25) -#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX53 (0x1 << 24) +#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 25) +#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 24) #define MXC_CCM_CLPCR_BYPASS_EMI_INT2_LPM_HS (0x1 << 23) +#define MX50_CCM_CLPCR_BYPASS_RNGB_LPM_HS (0x1 << 23) #define MXC_CCM_CLPCR_BYPASS_EMI_INT1_LPM_HS (0x1 << 22) #define MXC_CCM_CLPCR_BYPASS_EMI_SLOW_LPM_HS (0x1 << 21) #define MXC_CCM_CLPCR_BYPASS_EMI_FAST_LPM_HS (0x1 << 20) @@ -472,12 +489,13 @@ extern void __iomem *pll4_base; #define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) #define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3) #define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3) +#define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY (0x1 << 2) #define MXC_CCM_CLPCR_LPM_OFFSET (0) #define MXC_CCM_CLPCR_LPM_MASK (0x3) /* Define the bits in register CISR */ #define MXC_CCM_CISR_ARM_PODF_LOADED_MX51 (0x1 << 25) -#define MXC_CCM_CISR_ARM_PODF_LOADED_MX53 (0x1 << 26) +#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 26) #define MXC_CCM_CISR_TEMP_MON_ALARM (0x1 << 25) #define MXC_CCM_CISR_EMI_CLK_SEL_LOADED (0x1 << 23) #define MXC_CCM_CISR_PER_CLK_SEL_LOADED (0x1 << 22) @@ -490,6 +508,7 @@ extern void __iomem *pll4_base; #define MXC_CCM_CISR_COSC_READY (0x1 << 6) #define MXC_CCM_CISR_CKIH2_READY (0x1 << 5) #define MXC_CCM_CISR_CKIH_READY (0x1 << 4) +#define MX50_CCM_CISR_CAMP1_READY (0x1 << 4) #define MXC_CCM_CISR_FPM_READY (0x1 << 3) #define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2) #define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1) @@ -499,13 +518,14 @@ extern void __iomem *pll4_base; #define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED_MX51 (0x1 << 25) #define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED_MX51 (0x1 << 20) #define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED_MX51 (0x1 << 19) -#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED_MX53 (0x1 << 26) +#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 26) #define MXC_CCM_CIMR_MASK_TEMP_MON_ALARM (0x1 << 25) #define MXC_CCM_CIMR_MASK_EMI_CLK_SEL_LOADED (0x1 << 23) #define MXC_CCM_CIMR_MASK_PER_CLK_SEL_LOADED (0x1 << 22) #define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21) #define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED_MX53 (0x1 << 20) #define MXC_CCM_CIMR_MASK_EMI_SLOW_PODF_LOADED_MX53 (0x1 << 19) +#define MX50_CCM_CIMR_MASK_WEIM_PODF_LOADED (0x1 << 19) #define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18) #define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17) #define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16) @@ -513,8 +533,8 @@ extern void __iomem *pll4_base; #define MXC_CCM_CIMR_MASK_COSC_READY_MX51 (0x1 << 5) #define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4) #define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3) -/* MX53 */ -#define MXC_CCM_CIMR_MASK_COSC_READY_MX53 (0x1 << 6) +/* MX53/MX50 */ +#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 6) #define MXC_CCM_CIMR_MASK_CAMP2_READY (0x1 << 5) #define MXC_CCM_CIMR_MASK_CAMP1_READY (0x1 << 4) #define MXC_CCM_CIMR_MASK_LRF_PLL4 (0x1 << 3) @@ -542,6 +562,13 @@ extern void __iomem *pll4_base; #define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0) #define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7) +#define MX50_CCM_CCOSR_CKO1_SLOW_SEL (0x1 << 8) +#define MX50_CCM_CCOSR_CKO1_EN (0x1 << 7) +#define MX50_CCM_CCOSR_CKO1_DIV_OFFSET (4) +#define MX50_CCM_CCOSR_CKO1_DIV_MASK (0x7 << 4) +#define MX50_CCM_CCOSR_CKO1_SEL_OFFSET (0) +#define MX50_CCM_CCOSR_CKO1_SEL_MASK (0xF) + /* Define the bits in registers CCGRx */ #define MXC_CCM_CCGR_CG_MASK 0x3 @@ -729,6 +756,58 @@ extern void __iomem *pll4_base; #define MXC_CCM_CCGR7_CG1_OFFSET 2 #define MXC_CCM_CCGR7_CG0_OFFSET 0 +/* Define the bits in registers CSR2 */ +#define MXC_CCM_CSR2_ELCDIF_PIX_BUSY (0x1 << 9) +#define MXC_CCM_CSR2_EPDC_PIX_BUSY (0x1 << 8) +#define MXC_CCM_CSR2_EPDC_AXI_BUSY (0x1 << 4) +#define MXC_CCM_CSR2_DISPLAY_AXI_BUSY (0x1 << 3) + +/* Define the bits in registers CLKSEQ_BYPASS */ +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_OFFSET 14 +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_MASK (0x3 << 14) +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_OFFSET 12 +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_MASK (0x3 << 12) +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_OFFSET 4 +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_MASK (0x3 << 4) +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_OFFSET 2 +#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_MASK (0x3 << 2) + + +/* Define the bits in registers CLK_DDR */ +#define MXC_CCM_CLK_DDR_DDR_CLKGATE_OFFSET (30) +#define MXC_CCM_CLK_DDR_DDR_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_CLK_DDR_DDR_PFD_SEL (1 << 6) +#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_OFFSET (0) +#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK (0x3F) + +/* Define the bits in register DISPLAY_AXI */ +#define MXC_CCM_DISPLAY_AXI_CLKGATE_OFFSET (30) +#define MXC_CCM_DISPLAY_AXI_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_DISPLAY_AXI_DIV_OFFSET (0) +#define MXC_CCM_DISPLAY_AXI_DIV_MASK (0x3F) + +/* Define the bits in register EPDC_AXI */ +#define MXC_CCM_EPDC_AXI_CLKGATE_OFFSET (30) +#define MXC_CCM_EPDC_AXI_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_EPDC_AXI_DIV_OFFSET (0) +#define MXC_CCM_EPDC_AXI_DIV_MASK (0x3F) + +/* Define the bits in register EPDCPIX */ +#define MXC_CCM_EPDC_PIX_CLKGATE_OFFSET (30) +#define MXC_CCM_EPDC_PIX_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_EPDC_PIX_CLK_PRED_OFFSET (12) +#define MXC_CCM_EPDC_PIX_CLK_PRED_MASK (0x3 << 12) +#define MXC_CCM_EPDC_PIX_CLK_PODF_OFFSET (0) +#define MXC_CCM_EPDC_PIX_CLK_PODF_MASK (0xFFF) + +/* Define the bits in register ELCDIFPIX */ +#define MXC_CCM_ELCDIFPIX_CLKGATE_OFFSET (30) +#define MXC_CCM_ELCDIFPIX_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET (12) +#define MXC_CCM_ELCDIFPIX_CLK_PRED_MASK (0x3 << 12) +#define MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET (0) +#define MXC_CCM_ELCDIFPIX_CLK_PODF_MASK (0xFFF) + #define MXC_GPC_BASE (IO_ADDRESS(GPC_BASE_ADDR)) #define MXC_DPTC_LP_BASE (MXC_GPC_BASE + 0x80) #define MXC_DPTC_GP_BASE (MXC_GPC_BASE + 0x100) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 06f16db88993..fe842ea8e23d 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -17,6 +17,8 @@ #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/ipu.h> +#include <linux/fb.h> #include <linux/delay.h> #include <linux/uio_driver.h> #include <linux/mxc_scc2_driver.h> @@ -25,7 +27,6 @@ #include <mach/hardware.h> #include <mach/gpio.h> #include <mach/sdma.h> -#include "crm_regs.h" #include "mx51_pins.h" #include "devices.h" @@ -114,9 +115,31 @@ struct platform_device mxc_rtc_device = { .resource = rtc_resources, }; +static struct resource mxc_nand_resources[] = { + { + .flags = IORESOURCE_MEM, + .name = "NFC_AXI_BASE", + .start = MX51_NFC_BASE_ADDR_AXI, + .end = MX51_NFC_BASE_ADDR_AXI + SZ_8K - 1, + }, + { + .flags = IORESOURCE_MEM, + .name = "NFC_IP_BASE", + .start = NFC_BASE_ADDR + 0x00, + .end = NFC_BASE_ADDR + 0x34 - 1, + }, + { + .flags = IORESOURCE_IRQ, + .start = MXC_INT_NFC, + .end = MXC_INT_NFC, + }, +}; + struct platform_device mxc_nandv2_mtd_device = { .name = "mxc_nandv2_flash", .id = 0, + .resource = mxc_nand_resources, + .num_resources = ARRAY_SIZE(mxc_nand_resources), }; static struct resource imx_nfc_resources[] = { @@ -213,6 +236,46 @@ struct platform_device mxc_pwm_backlight_device = { .id = -1, }; +static struct resource flexcan0_resources[] = { + { + .start = CAN1_BASE_ADDR, + .end = CAN1_BASE_ADDR + 0x3FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_CAN1, + .end = MXC_INT_CAN1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_flexcan0_device = { + .name = "FlexCAN", + .id = 0, + .num_resources = ARRAY_SIZE(flexcan0_resources), + .resource = flexcan0_resources, +}; + +static struct resource flexcan1_resources[] = { + { + .start = CAN2_BASE_ADDR, + .end = CAN2_BASE_ADDR + 0x3FFF, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_CAN2, + .end = MXC_INT_CAN2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_flexcan1_device = { + .name = "FlexCAN", + .id = 1, + .num_resources = ARRAY_SIZE(flexcan1_resources), + .resource = flexcan1_resources, +}; + static struct resource ipu_resources[] = { { .start = MX51_IPU_CTRL_BASE_ADDR, @@ -236,6 +299,52 @@ struct platform_device mxc_ipu_device = { .resource = ipu_resources, }; +static struct resource epdc_resources[] = { + { + .start = EPDC_BASE_ADDR, + .end = EPDC_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_EPDC, + .end = MXC_INT_EPDC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device epdc_device = { + .name = "mxc_epdc_fb", + .id = -1, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(epdc_resources), + .resource = epdc_resources, +}; + +static struct resource elcdif_resources[] = { + { + .start = ELCDIF_BASE_ADDR, + .end = ELCDIF_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_ELCDIF, + .end = MXC_INT_ELCDIF, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device elcdif_device = { + .name = "mxc_elcdif_fb", + .id = -1, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(elcdif_resources), + .resource = elcdif_resources, +}; + struct platform_device mxc_fb_devices[] = { { .name = "mxc_sdc_fb", @@ -260,11 +369,37 @@ struct platform_device mxc_fb_devices[] = { }, }; -struct platform_device lcd_pdev = { - .name = "ccwmx51_display", - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - }, +static struct resource ldb_resources[] = { + { + .start = IOMUXC_BASE_ADDR, + .end = IOMUXC_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device mxc_ldb_device = { + .name = "mxc_ldb", + .id = -1, + .num_resources = ARRAY_SIZE(ldb_resources), + .resource = ldb_resources, +}; + + +struct platform_device lcd_pdev[] = { + { + .name = "ccwmx51_display", + .id = 0, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + }, + { + .name = "ccwmx51_display", + .id = 1, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + }, }; static struct resource vpu_resources[] = { @@ -508,6 +643,26 @@ struct platform_device mxc_ssi2_device = { .resource = ssi2_resources, }; +static struct resource esai_resources[] = { + { + .start = ESAI_BASE_ADDR, + .end = ESAI_BASE_ADDR + 0x100, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_ESAI, + .end = MXC_INT_ESAI, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_esai_device = { + .name = "mxc_esai", + .id = 0, + .num_resources = ARRAY_SIZE(esai_resources), + .resource = esai_resources, +}; + static struct resource tve_resources[] = { { .start = TVE_BASE_ADDR, @@ -623,6 +778,8 @@ int __init mxc_register_gpios(void) { if (cpu_is_mx51()) return mxc_gpio_init(mxc_gpio_ports, 4); + else if (cpu_is_mx50()) + return mxc_gpio_init(mxc_gpio_ports, 6); return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); } @@ -803,6 +960,29 @@ struct platform_device pata_fsl_device = { }, }; +static struct resource ahci_fsl_resources[] = { + { + .start = MX53_SATA_BASE_ADDR, + .end = MX53_SATA_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_SATA, + .end = MXC_INT_SATA, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ahci_fsl_device = { + .name = "ahci", + .id = 0, + .num_resources = ARRAY_SIZE(ahci_fsl_resources), + .resource = ahci_fsl_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + static u64 usb_dma_mask = DMA_BIT_MASK(32); static struct resource usbotg_resources[] = { @@ -970,23 +1150,31 @@ static struct resource mxc_gpu2d_resources[] = { #if defined(CONFIG_UIO_PDRV_GENIRQ) || defined(CONFIG_UIO_PDRV_GENIRQ_MODULE) static struct clk *gpu_clk; +static atomic_t *gpu_use_count; int gpu2d_open(struct uio_info *info, struct inode *inode) { - gpu_clk = clk_get(NULL, "gpu2d_clk"); - if (IS_ERR(gpu_clk)) - return PTR_ERR(gpu_clk); + int err = 0; - return clk_enable(gpu_clk); + if (atomic_inc_return(gpu_use_count) == 1) { + gpu_clk = clk_get(NULL, "gpu2d_clk"); + if (IS_ERR(gpu_clk)) + err = PTR_ERR(gpu_clk); + + err = clk_enable(gpu_clk); + } + return err; } int gpu2d_release(struct uio_info *info, struct inode *inode) { - if (IS_ERR(gpu_clk)) - return PTR_ERR(gpu_clk); + if (atomic_dec_and_test(gpu_use_count)) { + if (IS_ERR(gpu_clk)) + return PTR_ERR(gpu_clk); - clk_disable(gpu_clk); - clk_put(gpu_clk); + clk_disable(gpu_clk); + clk_put(gpu_clk); + } return 0; } @@ -1027,8 +1215,11 @@ static struct platform_device mxc_gpu2d_device = { static inline void mxc_init_gpu2d(void) { - dma_alloc_coherent(&mxc_gpu2d_device.dev, SZ_8K, &mxc_gpu2d_resources[1].start, GFP_DMA); - mxc_gpu2d_resources[1].end = mxc_gpu2d_resources[1].start + SZ_8K - 1; + void *gpu_mem; + gpu_mem = dma_alloc_coherent(&mxc_gpu2d_device.dev, SZ_64K, &mxc_gpu2d_resources[1].start, GFP_DMA); + mxc_gpu2d_resources[1].end = mxc_gpu2d_resources[1].start + SZ_64K - 1; + memset(gpu_mem, 0, SZ_64K); + gpu_use_count = gpu_mem + SZ_64K - 4; dma_alloc_coherent(&mxc_gpu2d_device.dev, 88 * SZ_1K, &mxc_gpu2d_resources[2].start, GFP_DMA); mxc_gpu2d_resources[2].end = mxc_gpu2d_resources[2].start + (88 * SZ_1K) - 1; @@ -1041,6 +1232,50 @@ static inline void mxc_init_gpu2d(void) } #endif +static struct resource mlb_resources[] = { + [0] = { + .start = MLB_BASE_ADDR, + .end = MLB_BASE_ADDR + 0x300, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MLB, + .end = MXC_INT_MLB, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_mlb_device = { + .name = "mxc_mlb", + .id = 0, + .num_resources = ARRAY_SIZE(mlb_resources), + .resource = mlb_resources, +}; + +static struct resource pxp_resources[] = { + { + .start = EPXP_BASE_ADDR, + .end = EPXP_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_EPXP, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device mxc_pxp_device = { + .name = "mxc-pxp", + .id = -1, + .num_resources = ARRAY_SIZE(pxp_resources), + .resource = pxp_resources, +}; + +struct platform_device mxc_pxp_client_device = { + .name = "pxp-device", + .id = -1, +}; + void __init mx5_init_irq(void) { unsigned long tzic_addr; @@ -1049,7 +1284,7 @@ void __init mx5_init_irq(void) tzic_addr = MX51_TZIC_BASE_ADDR_T01; else if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) tzic_addr = MX51_TZIC_BASE_ADDR; - else /* mx53 */ + else /* mx53 and mx50 */ tzic_addr = MX53_TZIC_BASE_ADDR; mxc_tzic_init_irq(tzic_addr); @@ -1266,7 +1501,7 @@ exit: int __init mxc_init_devices(void) { - if (cpu_is_mx53()) { + if (cpu_is_mx53() || cpu_is_mx50()) { sdma_resources[0].start -= MX53_OFFSET; sdma_resources[0].end -= MX53_OFFSET; mxc_w1_master_resources[0].start -= MX53_OFFSET; @@ -1287,6 +1522,10 @@ int __init mxc_init_devices(void) pwm1_resources[0].end -= MX53_OFFSET; pwm2_resources[0].start -= MX53_OFFSET; pwm2_resources[0].end -= MX53_OFFSET; + flexcan0_resources[0].start -= MX53_OFFSET; + flexcan0_resources[0].end -= MX53_OFFSET; + flexcan1_resources[0].start -= MX53_OFFSET; + flexcan1_resources[0].end -= MX53_OFFSET; mxc_fec_resources[0].start -= MX53_OFFSET; mxc_fec_resources[0].end -= MX53_OFFSET; vpu_resources[0].start -= MX53_OFFSET; @@ -1311,8 +1550,12 @@ int __init mxc_init_devices(void) ssi1_resources[0].end -= MX53_OFFSET; ssi2_resources[0].start -= MX53_OFFSET; ssi2_resources[0].end -= MX53_OFFSET; + esai_resources[0].start -= MX53_OFFSET; + esai_resources[0].end -= MX53_OFFSET; tve_resources[0].start -= MX53_OFFSET; tve_resources[0].end -= MX53_OFFSET; + dvfs_core_resources[0].start -= MX53_OFFSET; + dvfs_core_resources[0].end -= MX53_OFFSET; dvfs_per_resources[0].start -= MX53_OFFSET; dvfs_per_resources[0].end -= MX53_OFFSET; spdif_resources[0].start -= MX53_OFFSET; @@ -1347,13 +1590,24 @@ int __init mxc_init_devices(void) mxc_gpu2d_resources[0].end = MX53_GPU2D_BASE_ADDR + SZ_4K - 1; ipu_resources[0].start = MX53_IPU_CTRL_BASE_ADDR; ipu_resources[0].end = MX53_IPU_CTRL_BASE_ADDR + SZ_128M - 1; + mlb_resources[0].start -= MX53_OFFSET; + mlb_resources[0].end -= MX53_OFFSET; + mxc_nandv2_mtd_device.resource[0].start = + MX53_NFC_BASE_ADDR_AXI; + mxc_nandv2_mtd_device.resource[0].end = + MX53_NFC_BASE_ADDR_AXI + SZ_8K - 1; + mxc_nandv2_mtd_device.resource[1].start -= MX53_OFFSET; + mxc_nandv2_mtd_device.resource[1].end -= MX53_OFFSET; + ldb_resources[0].start -= MX53_OFFSET; + ldb_resources[0].end -= MX53_OFFSET; } else if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { scc_resources[1].start += 0x8000; scc_resources[1].end += 0x8000; } + if (cpu_is_mx51() || cpu_is_mx53()) + mxc_init_scc_iram(); - mxc_init_scc_iram(); mxc_init_gpu2d(); #if defined (CONFIG_MACH_CCWMX51JS) ccwmx51_init_devices(); diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index 13b9c2838fd5..8aaa128c561d 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -27,8 +27,11 @@ extern struct platform_device mxc_wdt_device; extern struct platform_device mxc_pwm1_device; extern struct platform_device mxc_pwm2_device; extern struct platform_device mxc_pwm_backlight_device; +extern struct platform_device mxc_flexcan0_device; +extern struct platform_device mxc_flexcan1_device; extern struct platform_device mxc_ipu_device; extern struct platform_device mxc_fb_devices[]; +extern struct platform_device mxc_ldb_device; extern struct platform_device mxcvpu_device; extern struct platform_device mxcscc_device; extern struct platform_device mxcspi1_device; @@ -41,6 +44,7 @@ extern struct platform_device mxc_dvfs_core_device; extern struct platform_device mxc_dvfs_per_device; extern struct platform_device mxc_ssi1_device; extern struct platform_device mxc_ssi2_device; +extern struct platform_device mxc_esai_device; extern struct platform_device mxc_alsa_spdif_device; extern struct platform_device mx51_lpmode_device; extern struct platform_device mx53_lpmode_device; @@ -51,6 +55,7 @@ extern struct platform_device mxc_sim_device; extern struct platform_device mxcsdhc1_device; extern struct platform_device mxcsdhc2_device; extern struct platform_device mxcsdhc3_device; +extern struct platform_device ahci_fsl_device; extern struct platform_device pata_fsl_device; extern struct platform_device gpu_device; extern struct platform_device mxc_fec_device; @@ -59,6 +64,12 @@ extern struct platform_device mxc_usbdr_otg_device; 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 lcd_pdev; +extern struct platform_device lcd_pdev[]; extern struct platform_device mxc_wm8753_device; +extern struct platform_device mxc_mlb_device; extern void __init ccwmx51_init_devices ( void ); +extern struct platform_device mxc_nandv2_mtd_device; +extern struct platform_device mxc_pxp_device; +extern struct platform_device mxc_pxp_client_device; +extern struct platform_device epdc_device; +extern struct platform_device elcdif_device; diff --git a/arch/arm/mach-mx5/devices_ccwmx51.c b/arch/arm/mach-mx5/devices_ccwmx51.c index 4e4a07f7c4a7..bd96da04bc62 100644 --- a/arch/arm/mach-mx5/devices_ccwmx51.c +++ b/arch/arm/mach-mx5/devices_ccwmx51.c @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/fsl_devices.h> #include <linux/spi/spi.h> +#include <linux/spi/ads7846.h> #include <linux/i2c.h> #include <linux/ata.h> #include <linux/regulator/consumer.h> @@ -34,6 +35,7 @@ #include <linux/mxcfb.h> #include <linux/pwm_backlight.h> #include <linux/smsc911x.h> +#include <linux/sysfs.h> #include <mach/common.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -45,6 +47,7 @@ #include <mach/gpio.h> #include <mach/mmc.h> #include <mach/mxc_dvfs.h> +#include <video/ad9389.h> #include "board-ccwmx51.h" #include "iomux.h" #include "crm_regs.h" @@ -60,65 +63,159 @@ #include <asm/mach/flash.h> #endif -#if defined(CONFIG_MTD_NAND_MXC) \ - || defined(CONFIG_MTD_NAND_MXC_MODULE) \ - || defined(CONFIG_MTD_NAND_MXC_V2) \ - || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \ - || defined(CONFIG_MTD_NAND_MXC_V3) \ - || defined(CONFIG_MTD_NAND_MXC_V3_MODULE) +#if defined(CONFIG_VIDEO_AD9389) || defined(CONFIG_VIDEO_AD9389_MODULE) +static int debug = 0; +#endif -extern void gpio_nand_active(void); -extern void gpio_nand_inactive(void); +#define AD9389_DBG 0x0001 +#define DBG(flag, fmt, args...) do { \ + if (debug & flag) \ + printk(fmt, ## args); \ + } while (0) -static int nand_init(void) +static u8 ccwmx51_mod_variant = 0; +static u8 ccwmx51_mod_rev = 0; +static u32 ccwmx51_mod_sn = 0; +static u8 ccwmx51_bb_rev = BASE_BOARD_REV; + +void ccwmx51_set_mod_variant(u8 variant) { - /* Configure the pins */ - gpio_nand_active(); - return 0; + ccwmx51_mod_variant = variant; +} +void ccwmx51_set_mod_revision(u8 revision) +{ + ccwmx51_mod_rev = revision; +} +void ccwmx51_set_mod_sn(u32 sn) +{ + ccwmx51_mod_sn = sn; } -static void nand_exit(void) +#ifdef CONFIG_SYSFS +static ssize_t ccwmx51_mod_variant_attr_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { - /* Free the pins */ - gpio_nand_inactive(); + return snprintf(buf, PAGE_SIZE, "%d\n", ccwmx51_mod_variant); } -struct flash_platform_data mxc_nand_data = { - .width = 1, - .init = nand_init, - .exit = nand_exit, -}; -#endif +static ssize_t ccwmx51_mod_rev_attr_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ccwmx51_mod_rev); +} -#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) -struct smsc911x_platform_config ccwmx51_smsc9118 = { - .flags = SMSC911X_USE_32BIT, - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, /* push-pull irq */ -}; -#endif +static ssize_t ccwmx51_mod_sn_attr_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ccwmx51_mod_sn); +} + +static ssize_t cccwmx51_bb_rev_attr_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ccwmx51_bb_rev); +} + +static struct kobj_attribute ccwmx51_mod_variant_attr = + __ATTR(mod_variant, S_IRUGO, ccwmx51_mod_variant_attr_show, NULL); +static struct kobj_attribute ccwmx51_mod_rev_attr = + __ATTR(mod_rev, S_IRUGO, ccwmx51_mod_rev_attr_show, NULL); +static struct kobj_attribute ccwmx51_mod_sn_attr = + __ATTR(mod_sn, S_IRUGO, ccwmx51_mod_sn_attr_show, NULL); +static struct kobj_attribute ccwmx51_bb_rev_attr = + __ATTR(bb_rev, S_IRUGO, cccwmx51_bb_rev_attr_show, NULL); + +int ccwmx51_create_sysfs_entries(void) +{ + struct kobject *ccwmx51_kobj; + int ret; + + ccwmx51_kobj = kobject_create_and_add("ccwmx51", kernel_kobj); + if (!ccwmx51_kobj) { + printk(KERN_WARNING "kobject_create_and_add ccwmx51 failed\n"); + return -EINVAL; + } + + ret = sysfs_create_file(ccwmx51_kobj, &ccwmx51_mod_variant_attr.attr); + if (ret) { + printk(KERN_ERR + "Unable to register sysdev entry for ccwmx51 hardware variant\n"); + return ret; + } + ret = sysfs_create_file(ccwmx51_kobj, &ccwmx51_mod_rev_attr.attr); + if (ret) { + printk(KERN_ERR + "Unable to register sysdev entry for ccwmx51 hardware revision\n"); + return ret; + } + ret = sysfs_create_file(ccwmx51_kobj, &ccwmx51_mod_sn_attr.attr); + if (ret) { + printk(KERN_ERR + "Unable to register sysdev entry for ccwmx51 hardware SN\n"); + return ret; + } + ret = sysfs_create_file(ccwmx51_kobj, &ccwmx51_bb_rev_attr.attr); + if (ret) { + printk(KERN_ERR + "Unable to register sysdev entry for ccwmx51 base board hardware revision\n"); + return ret; + } + + return 0; +} +#endif /* CONFIG_SYSFS */ + +#if defined(CONFIG_HAS_EARLY_USER_LEDS) +void ccwmx51_user_led(int led, int val) +{ + __iomem void *base; + u32 reg, mask; + + if (led == 1) + mask = 1 << 10; + else if (led == 2) + mask = 1 << 9; + else + return; + + base = ioremap(GPIO3_BASE_ADDR, SZ_4K); + reg = __raw_readl(base); + + if (val) + reg |= mask; + else + reg &= ~mask; + + __raw_writel(reg, base); + iounmap(base); +} +#endif /* CONFIG_HAS_EARLY_USER_LEDS */ #if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) static int sdhc_write_protect(struct device *dev) { - unsigned short rc = 0; + unsigned short rc = 0; - if (to_platform_device(dev)->id == 0) - rc = 0; /* Not supported WP on JSK board, therefore write is enabled */ - else if (to_platform_device(dev)->id == 2) - rc = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_NANDF_CS1)); - return rc; + if (to_platform_device(dev)->id == 0) + rc = 0; /* Not supported WP on JSK board, therefore write is enabled */ + else if (to_platform_device(dev)->id == 2) + rc = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_NANDF_CS1)); + return rc; } static unsigned int sdhc_get_card_det_status(struct device *dev) { - int ret = 0; + int ret = 1; - if (to_platform_device(dev)->id == 0) - ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0)); - else if (to_platform_device(dev)->id == 2) - ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO_NAND)); - return ret; + if (to_platform_device(dev)->id == 0) +#ifdef CONFIG_JSCCWMX51_V1 + ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0)); +#else + ret = 0; +#endif + else if (to_platform_device(dev)->id == 2) + ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO_NAND)); + return ret; } struct mxc_mmc_platform_data mmc1_data = { @@ -135,7 +232,7 @@ struct mxc_mmc_platform_data mmc1_data = { struct mxc_mmc_platform_data mmc3_data = { .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | - MMC_VDD_31_32, + MMC_VDD_31_32, .caps = MMC_CAP_4_BIT_DATA, .min_clk = 150000, .max_clk = 50000000, @@ -145,12 +242,73 @@ struct mxc_mmc_platform_data mmc3_data = { .clock_mmc = "esdhc_clk", .power_mmc = NULL, }; + +void ccwmx51_register_sdio(int interface) +{ + switch (interface) { + case 0: + mxcsdhc1_device.resource[2].start = CCWMX51_SD1_CD_IRQ; + mxcsdhc1_device.resource[2].end = CCWMX51_SD1_CD_IRQ; + mxc_register_device(&mxcsdhc1_device, &mmc1_data); + break; + case 2: + mxcsdhc3_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO_NAND); + mxcsdhc3_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO_NAND); + mxc_register_device(&mxcsdhc3_device, &mmc3_data); + break; + } +} +#endif + +#if defined(CONFIG_MTD_NAND_MXC) \ + || defined(CONFIG_MTD_NAND_MXC_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V2) \ + || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V3) \ + || defined(CONFIG_MTD_NAND_MXC_V3_MODULE) + +extern void gpio_nand_active(void); +extern void gpio_nand_inactive(void); + +static int nand_init(void) +{ + /* Configure the pins */ + gpio_nand_active(); + return 0; +} + +static void nand_exit(void) +{ + /* Free the pins */ + gpio_nand_inactive(); +} + +struct flash_platform_data mxc_nand_data = { + .width = 1, + .init = nand_init, + .exit = nand_exit, +}; +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +struct smsc911x_platform_config ccwmx51_smsc9118 = { + .flags = SMSC911X_USE_32BIT, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, /* push-pull irq */ +}; #endif #if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) -struct resource mxcfb_resources[1] = { +struct resource mxcfb_resources[2] = { { - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_MEM, + .start = 0, + .end = 0, + }, + { + .flags = IORESOURCE_MEM, + .start = 0, + .end = 0, }, }; #endif @@ -158,13 +316,24 @@ struct resource mxcfb_resources[1] = { static struct i2c_board_info ccwmx51_i2c_devices[] __initdata = { #if defined(CONFIG_INPUT_MMA7455L) || defined(CONFIG_INPUT_MMA7455L_MODULE) { - I2C_BOARD_INFO("mma7455l", 0x1d), + I2C_BOARD_INFO("mma7455l", 0x1d), .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_7), }, #endif #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE) { - I2C_BOARD_INFO("wm8753", 0x1A), + I2C_BOARD_INFO("wm8753", 0x1A), + }, +#endif + +#if defined (CONFIG_MXC_CAMERA_MICRON111_1) || defined(CONFIG_MXC_CAMERA_MICRON111_1_MODULE) + { + I2C_BOARD_INFO("mt9v111_1", 0xB8>>1), + }, +#endif +#if defined (CONFIG_MXC_CAMERA_MICRON111_2) || defined(CONFIG_MXC_CAMERA_MICRON111_2_MODULE) + { + I2C_BOARD_INFO("mt9v111_2", 0x90>>1), }, #endif }; @@ -183,16 +352,54 @@ struct mxc_i2c_platform_data mxci2c_hs_data = { }; #if defined(CONFIG_SPI_MXC_SELECT1_SS1) && (defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)) +#if defined(CONFIG_CCWMX51_SECOND_TOUCH) +static int touch_pendown_state(void) +{ + return gpio_get_value(IOMUX_TO_GPIO(SECOND_TS_IRQ_PIN)) ? 0 : 1; +} + +static struct ads7846_platform_data ccwmx51js_touch_data = { + .model = 7843, + .x_min = 0, + .y_min = 0, + .x_max = 4095, + .y_max = 4095, + .get_pendown_state = touch_pendown_state, + .buflen = 10, + .skip_samples = 2, + .rotate = 0, +}; + +static struct spi_board_info ccwmx51_2nd_touch[] = { + { + .modalias = "ads7846", + .max_speed_hz = 500000, + .irq = IOMUX_TO_IRQ(SECOND_TS_IRQ_PIN), + .bus_num = 1, + .chip_select = 3, + .platform_data = &ccwmx51js_touch_data, + }, +}; + +void ccwmx51_init_2nd_touch(void) +{ + ccwmx51_2nd_touch_gpio_init(); + spi_register_board_info(ccwmx51_2nd_touch, ARRAY_SIZE(ccwmx51_2nd_touch)); +} +#else +void ccwmx51_init_2nd_touch(void) {} +#endif + static struct spi_board_info spi_devices[] = { #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) - { /* SPIDEV */ - .modalias = "spidev", - .max_speed_hz = 6000000, - .bus_num = 1, - .chip_select = 1, + { /* SPIDEV */ + .modalias = "spidev", + .max_speed_hz = 6000000, + .bus_num = 1, + .chip_select = 1, }, - /* Add here other SPI devices, if any... */ #endif + /* Add here other SPI devices, if any... */ }; void ccwmx51_init_spidevices(void) @@ -234,7 +441,7 @@ struct mxc_w1_config mxc_w1_data = { #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) static struct resource smsc911x_device_resources[] = { - { + { .name = "smsc911x-memory", .start = CS5_BASE_ADDR, .end = CS5_BASE_ADDR + SZ_4K - 1, @@ -248,10 +455,10 @@ static struct resource smsc911x_device_resources[] = { }; struct platform_device smsc911x_device = { - .name = "smsc911x", - .id = -1, - .num_resources = ARRAY_SIZE(smsc911x_device_resources), - .resource = smsc911x_device_resources, + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_device_resources), + .resource = smsc911x_device_resources, }; /* WEIM registers */ @@ -261,9 +468,9 @@ struct platform_device smsc911x_device = { #define CSRCR2 0x0C #define CSWCR1 0x10 -static void __init ccwmx51_init_ext_eth_mac(void) +static void ccwmx51_init_ext_eth_mac(void) { - __iomem u32 *weim_vbaddr; + __iomem void *weim_vbaddr; weim_vbaddr = ioremap(WEIM_BASE_ADDR, SZ_4K); if (weim_vbaddr == 0) { @@ -276,11 +483,11 @@ static void __init ccwmx51_init_ext_eth_mac(void) * RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0, APR=0 * WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0, WEN=0, WCSA=0 */ - writel(0x00420081, (unsigned int)(weim_vbaddr) + 0x78 + CSGCR1); - writel(0, (unsigned int)(weim_vbaddr) + 0x78 + CSGCR2); - writel(0x32260000, (unsigned int)(weim_vbaddr) + 0x78 + CSRCR1); - writel(0, (unsigned int)(weim_vbaddr) + 0x78 + CSRCR2); - writel(0x72080f00, (unsigned int)(weim_vbaddr) + 0x78 + CSWCR1); + __raw_writel(0x00420081, (u32)weim_vbaddr + 0x78 + CSGCR1); + __raw_writel(0, (u32)weim_vbaddr + 0x78 + CSGCR2); + __raw_writel(0x32260000, (u32)weim_vbaddr + 0x78 + CSRCR1); + __raw_writel(0, (u32)weim_vbaddr + 0x78 + CSRCR2); + __raw_writel(0x72080f00, (u32)weim_vbaddr + 0x78 + CSWCR1); iounmap(weim_vbaddr); @@ -319,10 +526,6 @@ struct mxc_dvfs_platform_data dvfs_core_data = { .ccm_cdcr_reg_addr = MXC_CCM_CDCR, .ccm_cacrr_reg_addr = MXC_CCM_CACRR, .ccm_cdhipr_reg_addr = MXC_CCM_CDHIPR, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -364,90 +567,606 @@ struct platform_pwm_backlight_data mxc_pwm_backlight_data = { }; struct mxc_audio_platform_data wm8753_data = { - .ssi_num = 1, - .src_port = 2, - .ext_port = 3, - .sysclk = 12000000, + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .sysclk = 0 /* Set on the fly */, }; -struct mxc_fb_platform_data mx51_fb_data[] = { - /*VGA*/ +struct mxc_fb_platform_data mx51_fb_data[2] = { + /* DISP0 */ + { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1024x768M-16@60", /* Default */ + }, + /* DISP1 */ { - .interface_pix_fmt = IPU_PIX_FMT_RGB24, - .mode_str = "1024x768M-16@60", /* Default */ + .interface_pix_fmt = IPU_PIX_FMT_RGB666, + .mode_str = "800x480-16@60", /* Default */ } }; -#if defined(CONFIG_UIO_PDRV_GENIRQ) || defined(CONFIG_UIO_PDRV_GENIRQ_MODULE) -struct uio_info gpu2d_platform_data = { - .name = "imx_gpu2d", - .version = "1", - .irq = MXC_INT_GPU2_IRQ, - .open = gpu2d_open, - .release = gpu2d_release, - .mmap = gpu2d_mmap, -}; -#endif #if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) -struct ccwmx51_lcd_pdata * plcd_platform_data; +struct ccwmx51_lcd_pdata plcd_platform_data[2]; -struct ccwmx51_lcd_pdata * ccwmx51_get_display(char *name) +#if defined(CONFIG_VIDEO_AD9389) || defined(CONFIG_VIDEO_AD9389_MODULE) +static u32 ccwmx51_get_max_video_pclk(void) +{ + /** + * TODO get this value from the clock subsystem. + * 133MHz seems to cause problems with the ext clk. + */ + return KHZ2PICOS(132000); +} +#endif + +#if defined(CONFIG_CCWMX51_DISP1) +static char *video2_options[FB_MAX] __read_mostly; +static int ofonly2 __read_mostly; + +int fb2_get_options(char *name, char **option) +{ + char *opt, *options = NULL; + int opt_len, retval = 0; + int name_len = strlen(name), i; + + if (name_len && ofonly2 && strncmp(name, "offb", 4)) + retval = 1; + + if (name_len && !retval) { + for (i = 0; i < FB_MAX; i++) { + if (video2_options[i] == NULL) + continue; + opt_len = strlen(video2_options[i]); + if (!opt_len) + continue; + opt = video2_options[i]; + if (!strncmp(name, opt, name_len) && + opt[name_len] == ':') + options = opt + name_len + 1; + } + } + if (options && !strncmp(options, "off", 3)) + retval = 1; + + if (option) + *option = options; + + return retval; +} + +static int __init video2_setup(char *options) +{ + int i, global = 0; + + if (!options || !*options) + global = 1; + + if (!global && !strncmp(options, "ofonly", 6)) { + ofonly2 = 1; + global = 1; + } + + if (!global && !strstr(options, "fb:")) { + fb_mode_option = options; + global = 1; + } + + if (!global) { + for (i = 0; i < FB_MAX; i++) { + if (video2_options[i] == NULL) { + video2_options[i] = options; + break; + } + } + } + + return 1; +} +__setup("video2=", video2_setup); +#endif /* defined(CONFIG_CCWMX51_DISP1) */ + +struct ccwmx51_lcd_pdata * ccwmx51_find_video_config(struct ccwmx51_lcd_pdata list[], + int len, + const char *name) { -#if defined(CONFIG_CCWMX51_LQ070Y3DG3B) || defined(CONFIG_CCWMX51_CUSTOM) int i; - for (i = 0; i < ARRAY_SIZE(lcd_display_list); i++) - if (!strncmp(lcd_display_list[i].fb_pdata.mode->name, - name, strlen(lcd_display_list[i].fb_pdata.mode->name))) - return &lcd_display_list[i]; + for (i = 0; i < len; i++) + if (!strncmp(list[i].fb_pdata.mode->name, + name, strlen(list[i].fb_pdata.mode->name))) + return &list[i]; + return NULL; +} + +static char *ccwmx51_get_video_cmdline_opt(int dispif, const char *str) +{ + char *options = NULL; + int ret = 1; + int len = strlen(str); + +#if defined(CONFIG_CCWMX51_DISP0) + if (dispif == 0) { + ret = fb_get_options("displayfb", &options); + } +#endif +#if defined(CONFIG_CCWMX51_DISP1) + if (dispif == 1) { + ret = fb2_get_options("displayfb", &options); + } #endif + if (ret || !options) + return NULL; + if (!len || !strncasecmp(options, str, len)) + return &options[len]; + return NULL; } -int __init ccwmx51_init_fb(void) +#if defined(CONFIG_VIDEO_AD9389) || defined(CONFIG_VIDEO_AD9389_MODULE) +static void fb_dump_mode(const char *str, const struct fb_videomode *vm) { - char *options = NULL, *p; + if (!(debug & AD9389_DBG)) + return; + if (vm == NULL) + return; - if (fb_get_options("displayfb", &options)) - pr_warning("no display information available in command line\n"); + printk(KERN_INFO "%s geometry %u %u %u\n", + str, vm->xres, vm->yres, vm->pixclock); + printk(KERN_INFO "%s timings %u %u %u %u %u %u %u\n", str, vm->pixclock, vm->left_margin, + vm->right_margin, vm->upper_margin, vm->lower_margin, vm->hsync_len, vm->vsync_len); + printk(KERN_INFO "%s flag %u sync %u vmode %u %s\n", str, vm->flag, vm->sync, vm->vmode, + vm->flag & FB_MODE_IS_FIRST ? "preferred" : ""); +} - if (!options) - return -ENODEV; +static void fb_dump_var(const char *str, struct fb_var_screeninfo *var) +{ + if (!(debug & AD9389_DBG)) + return; + if (var == NULL) + return; - if (!strncasecmp(options, "VGA", 3)) { - pr_info("VGA interface is primary\n"); + printk(KERN_INFO "%s geometry %u %u %u %u\n", + str, var->xres, var->yres, var->xres_virtual, var->yres_virtual); + printk(KERN_INFO "%s offset %u %u %u %u %u\n", + str, var->xoffset, var->yoffset, var->height, var->width, var->bits_per_pixel); + printk(KERN_INFO "%s timings %u %u %u %u %u %u %u\n", + str, var->pixclock, var->left_margin, var->right_margin, + var->upper_margin, var->lower_margin, var->hsync_len, var->vsync_len); + printk(KERN_INFO "%s accel_flags %u sync %u vmode %u\n", + str, var->accel_flags, var->sync, var->vmode); + printk(KERN_INFO "%d bpp\n", var->bits_per_pixel); +} + +enum hdmi_mode get_hdmi_mode(struct ad9389_dev *ad9389, struct fb_videomode **vm, char **str, unsigned int *vpclk, int *ext_clk) +{ + struct ad9389_pdata *pdata = ad9389->client->dev.platform_data; + struct ccwmx51_lcd_pdata *panel; + char *p, *temp; + + if ((p = ccwmx51_get_video_cmdline_opt(pdata->dispif, "HDMI")) != NULL) { + DBG(AD9389_DBG, "HDMI: %s config on DISP%d\n", p, pdata->dispif); /* Get the desired configuration provided by the bootloader */ - if (options[3] != '@') { - pr_info("Video resolution for VGA interface not provided, using default\n"); - /* TODO set default video here */ + if (vpclk != NULL ) { + *vpclk = 0; + /* Parse pclk, it was passed through cmdline */ + if ((temp = strstr(p, "pclk=")) != NULL) { + *vpclk = (unsigned int)simple_strtoul(temp + 5, NULL, 10); + if (*vpclk < ccwmx51_get_max_video_pclk()) + *vpclk = 0; + } + DBG(AD9389_DBG, "HDMI: using cmdline pclk %d\n", *vpclk); + } + if (ext_clk != NULL ) { + /* For single display, default is internal clk and can be overrided by cmdline */ +#if !defined(CONFIG_CCWMX51_DISP0) || !defined(CONFIG_CCWMX51_DISP1) + *ext_clk = 1; +#else + *ext_clk = 0; +#endif + /* Parse ext_clk, it was passed through cmdline */ + if ((temp = strstr(p, "int_clk")) != NULL) + *ext_clk = 0; + if ((temp = strstr(p, "ext_clk")) != NULL) + *ext_clk = 1; + DBG(AD9389_DBG, "HDMI: using %s\n", ext_clk ? "ext_clk" : "int_clk"); + } + if (*p++ != '@') { + pr_info("Video resolution for HDMI interface not provided, using auto\n"); + return MODE_AUTO; + } else if (!strncasecmp(p, "auto@", 5)) { + *str = p + 5; + if ((temp = strchr(*str, ',')) != NULL) + *temp = '\0'; + DBG(AD9389_DBG, "HDMI: auto string %s\n", *str); + return MODE_AUTO_STRING; + } else if (!strncasecmp(p, "auto", 4)) { + DBG(AD9389_DBG, "HDMI: auto\n"); + return MODE_AUTO; + } else if ((panel = ccwmx51_find_video_config(ad9389_panel_list, + ARRAY_SIZE(ad9389_panel_list), + p)) != NULL) { + *vm = panel->fb_pdata.mode; + memcpy(&mx51_fb_data[pdata->dispif], + &plcd_platform_data[pdata->dispif].fb_pdata, + sizeof(struct mxc_fb_platform_data)); + DBG(AD9389_DBG, "HDMI: forced mode\n"); + return MODE_FORCED; } else { - options = &options[4]; - if (((p = strsep (&options, "@")) != NULL) && *p) { - if (!strcmp(p, "640x480x16")) { - strcpy(mx51_fb_data[0].mode_str, "640x480M-16@60"); - } else if (!strcmp(p, "800x600x16")) { - strcpy(mx51_fb_data[0].mode_str, "800x600M-16@60"); - } else if (!strcmp(p, "1024x768x16")) { - strcpy(mx51_fb_data[0].mode_str, "1024x768M-16@60"); - } else if (!strcmp(p, "1280x1024x16")) { - strcpy(mx51_fb_data[0].mode_str, "1280x1024M-16@60"); - } else - pr_warning("Unsuported video resolution: %s, using default\n", p); + *str = p; + if ((temp = strchr(*str, ',')) != NULL) + *temp = '\0'; + DBG(AD9389_DBG, "HDMI: string %s\n", *str); + return MODE_STRING; + } + } + return MODE_UNKNOWN; +} + +#define AD9389_STR_LEN 30 +static void mxc_videomode_to_var(struct ad9389_dev *ad9389, struct fb_var_screeninfo *var) +{ + struct fb_info *info = ad9389->fbi; + const struct fb_videomode *fbvmode = NULL; + char *modestr = NULL, str[AD9389_STR_LEN]; + unsigned int tpclk; + int modeidx, ext_clk; + enum hdmi_mode mode; + + var->bits_per_pixel = CONFIG_CCWMX51_DEFAULT_VIDEO_BPP; /* Set default bpp */ + /* First, check if we have a predefined mode through the kernel command line */ + mode = get_hdmi_mode(ad9389, (struct fb_videomode **)&fbvmode, &modestr, &tpclk, &ext_clk); + if (mode == MODE_AUTO) { + /* auto, or no video mode provided */ + strncpy(str, "HDMI auto selected mode:", AD9389_STR_LEN - 1); + fbvmode = fb_find_best_mode(var, &info->modelist); + if (!fbvmode) { + fbvmode = fb_find_best_display(&info->monspecs, &info->modelist); + if (!fbvmode) { + printk(KERN_WARNING + "HDMI: unable to find a valid video mode/screen," + " try forcing a mode\n"); + /* Use default... */ + fbvmode = &ad9389_1024x768x24; + strncpy(str, "HDMI default mode:", AD9389_STR_LEN - 1); + } + } + } else if (mode == MODE_FORCED) { + /* Selected video mode through cmd line parameters provided */ + strncpy(str, "HDMI forced mode:", AD9389_STR_LEN - 1); + } else if ((mode == MODE_STRING || mode == MODE_AUTO_STRING) && modestr) { + DBG(AD9389_DBG, "HDMI mode string: %s\n", modestr); + modeidx = fb_find_mode(var, info, modestr, + info->monspecs.modedb, + info->monspecs.modedb_len, + NULL, var->bits_per_pixel); + if (!(modeidx == 1 || modeidx == 1)) { + DBG(AD9389_DBG, "HDMI: unable to find valid mode (%s)\n", modestr); + return; + } + strncpy(str, "HDMI string mode:", AD9389_STR_LEN - 1); + } + str[AD9389_STR_LEN - 1] = 0; + if ((mode == MODE_AUTO) || (mode == MODE_FORCED)) { + fb_dump_mode(str, fbvmode); + fb_videomode_to_var(var, fbvmode); + } + + if (ext_clk) + var->sync |= FB_SYNC_EXT; + + /* Check if clock must be readjusted */ + if (tpclk != 0) + var->pixclock = tpclk; + + fb_dump_var(str, var); +} + +/** + * This function parses the list of supported video modes (got from fb_edid_to_monspecs) and + * filters out not supported configurations + */ +static void mxcfb_vmode_to_modelist(struct fb_videomode *modedb, int num, + struct list_head *head, struct fb_var_screeninfo *var) +{ + int i, xres = 0, yres = 0, aspratio = 0; + + INIT_LIST_HEAD(head); + + /** + * Add the modes we got through the monitor specs, filtering out those + * unsupported configurations. + */ + for (i = 0; i < num; i++) { + struct list_head *pos, *n; + struct fb_modelist *modelist; + int remove, vmaspratio; + + remove = 0; + vmaspratio = -1; + + /* Use the preferred mode to compute the aspect ratio */ + if (modedb[i].flag & FB_MODE_IS_FIRST) { + DBG(AD9389_DBG, "PREFERRED: %ux%u%s%u pclk=%u\n", + modedb[i].xres, modedb[i].yres, + (modedb[i].vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modedb[i].refresh, modedb[i].pixclock); + + aspratio = modedb[i].xres * 10 / modedb[i].yres; + DBG(AD9389_DBG, "Aspect Ratio: %d\n", aspratio); + } + + if (modedb[i].yres) + vmaspratio = modedb[i].xres * 10 / modedb[i].yres; + + if (vmaspratio != aspratio) { + DBG(AD9389_DBG, "REMOVED: %ux%u%s%u pclk=%u (aspect ratio)\n", + modedb[i].xres, modedb[i].yres, + (modedb[i].vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modedb[i].refresh, modedb[i].pixclock); + continue; + } + + /* Interlaced not supported */ + if (modedb[i].vmode & FB_VMODE_INTERLACED) { + DBG(AD9389_DBG, "REMOVED: %ux%u%s%u pclk=%u (interlaced modes not supported)\n", + modedb[i].xres, modedb[i].yres, + (modedb[i].vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modedb[i].refresh, modedb[i].pixclock); + continue; + } + + /* If clock exceeds the max pixel clock supported, remove that video mode */ + if ((modedb[i].pixclock * 115 / 100) < ccwmx51_get_max_video_pclk()) { + DBG(AD9389_DBG, "REMOVED: %ux%u%s%u pclk=%u (exceed %u limit)\n", + modedb[i].xres, modedb[i].yres, + (modedb[i].vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modedb[i].refresh, modedb[i].pixclock, ccwmx51_get_max_video_pclk()); + continue; + } + + /* If over the pixel clock limix, but close enough, set the max pixel clock freq */ + if (modedb[i].pixclock < ccwmx51_get_max_video_pclk()) + modedb[i].pixclock = ccwmx51_get_max_video_pclk(); + + /** + * Adjust timing to IPU restrictions (better done here, to avoid ipu driver to + * incorrectly calculate settings based on our configuration). + */ + if (modedb[i].lower_margin < 2) { + /* This will not affect much, so we dont adjust the pixel clock */ + DBG(AD9389_DBG, "ADJUSTED: lower margin from %u to 2\n", + modedb[i].lower_margin); + modedb[i].lower_margin = 2; + } + + /** + * Remove duplicated modes, selecting the best modes accordingly to the + * platform video constraints. + */ + list_for_each_safe(pos, n, head) { + modelist = list_entry(pos, struct fb_modelist, list); + + if ((modelist->mode.xres == modedb[i].xres) && + (modelist->mode.yres == modedb[i].yres)) { + + if (modedb[i].pixclock == ccwmx51_get_max_video_pclk()) { + /* If current mode pixclk is set to max clock, do not + * add this mode and use the existing one. */ + remove = 1; + } else if ((modelist->mode.refresh == modedb[i].refresh) && + (modedb[i].flag & FB_MODE_IS_DETAILED)) { + DBG(AD9389_DBG, "REMOVED: %ux%u%s%u pclk=%u (duplicated)\n", + modelist->mode.xres, modelist->mode.yres, + (modelist->mode.vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modelist->mode.refresh, modelist->mode.pixclock); + list_del(pos); + kfree(pos); + } else { + /* Do not add this mode, it is not a detailed timing */ + remove = 1; + } } } - } else { - if ((plcd_platform_data = ccwmx51_get_display(options)) != NULL) { - memcpy(&mx51_fb_data[0], &plcd_platform_data->fb_pdata, sizeof(struct mxc_fb_platform_data)); - plcd_platform_data->vif = 0; /* Select video interface 0 */ + + if (!remove) { + fb_add_videomode(&modedb[i], head); + DBG(AD9389_DBG, "ADDING: Video mode %ux%u%s%u pclk=%u, %s detailed\n", + modedb[i].xres, modedb[i].yres, + (modedb[i].vmode & FB_VMODE_INTERLACED ) ? "i@" : "@", + modedb[i].refresh, modedb[i].pixclock, + (modedb[i].flag & FB_MODE_IS_DETAILED) ? "" : "no"); + + if (modedb[i].xres > xres && modedb[i].yres > yres) { + xres = modedb[i].xres; + yres = modedb[i].yres; + } } } + + /* Update var->xres and var->yres, used to determine the best video mode*/ + if (var->xres != xres || var->yres != yres) { + var->xres = xres; + var->yres = yres; + } +} + +static int ccwmx51_hdmi_hw_init(struct ad9389_dev *ad9389) +{ + struct ad9389_pdata *pdata = ad9389->client->dev.platform_data; + + if (pdata->dispif == 0) { + mxc_request_iomux(AD9389_GPIO_IRQ, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION); + mxc_iomux_set_pad(AD9389_GPIO_IRQ, PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | + PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE | + PAD_CTL_DRV_VOT_HIGH); + + gpio_request(IOMUX_TO_GPIO(AD9389_GPIO_IRQ), "ad9389_irq"); + gpio_direction_input(IOMUX_TO_GPIO(AD9389_GPIO_IRQ)); + + set_irq_type(IOMUX_TO_GPIO(AD9389_GPIO_IRQ), IRQ_TYPE_EDGE_BOTH); + } + + /* Configure here the hot plug detection for HDMI on DISP1 */ + /* if (pdata->dispif == 1) { } */ + + gpio_video_active(pdata->dispif, + PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + return 0; } -device_initcall(ccwmx51_init_fb); + +static void ccwmx51_hdmi_disp_connected(struct ad9389_dev *ad9389) +{ + printk(KERN_DEBUG "%s: display connected\n", __func__); +} + +static void ccwmx51_hdmi_disp_disconnected(struct ad9389_dev *ad9389) +{ + printk(KERN_DEBUG "%s: display disconnected\n", __func__); +} + +static struct ad9389_pdata hdmi_pdata = { + .hw_init = &ccwmx51_hdmi_hw_init, + .disp_connected = &ccwmx51_hdmi_disp_connected, + .disp_disconnected = &ccwmx51_hdmi_disp_disconnected, + .vmode_to_modelist = &mxcfb_vmode_to_modelist, + .vmode_to_var = &mxc_videomode_to_var, + .edid_addr = (0x7e >> 1), + .dispif = 0, +}; + +struct i2c_board_info ccwmx51_hdmi[] __initdata = { + { + I2C_BOARD_INFO("ad9389", 0x39), + .irq = IOMUX_TO_IRQ(AD9389_GPIO_IRQ), + .platform_data = &hdmi_pdata, + }, +}; +#endif + +#define MAX_VIDEO_IF 2 +int __init ccwmx51_init_fb(void) +{ + struct ccwmx51_lcd_pdata *panel; + char *p, *mstr; + int i; + + plcd_platform_data[0].vif = -1; + plcd_platform_data[1].vif = -1; + + for (i = 0; i < MAX_VIDEO_IF; i++) { +#if !defined(CONFIG_CCWMX51_DISP0) + if (i == 0) continue; +#endif +#if !defined(CONFIG_CCWMX51_DISP1) + if (i == 1) continue; +#endif + if ((p = ccwmx51_get_video_cmdline_opt(i, "HDMI")) != NULL) { +#if defined(CONFIG_VIDEO_AD9389) || defined(CONFIG_VIDEO_AD9389_MODULE) + pr_info("HDMI interface in DISP%d\n", i); + i2c_register_board_info(1, ccwmx51_hdmi, 1); +#else + pr_info("HDMI selected in DISP%d, but driver unavailable\n", i); + continue; +#endif + } else if ((p = ccwmx51_get_video_cmdline_opt(i, "LCD")) != NULL) { + pr_info("LCD interface in DISP%d", i); + if (*p++ != '@') { + pr_info("Panel not provided, video interface will be disabled\n"); + continue; + } + if ((panel = ccwmx51_find_video_config(lcd_panel_list, + ARRAY_SIZE(lcd_panel_list), + p)) != NULL) { + pr_info("Panel: %s", p); + memcpy(&plcd_platform_data[i], + panel, + sizeof(struct ccwmx51_lcd_pdata)); + memcpy(&mx51_fb_data[i], + &plcd_platform_data[i].fb_pdata, + sizeof(struct mxc_fb_platform_data)); + plcd_platform_data[i].vif = i; + mxc_register_device(&lcd_pdev[i], (void *)&plcd_platform_data[i]); + } + } else if ((p = ccwmx51_get_video_cmdline_opt(i, "VGA")) != NULL) { + pr_info("VGA interface in DISP%d\n", i); + gpio_video_active(i, PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + mstr = p - 3; + + /* Get the desired configuration provided by the bootloader */ + if (*p++ != '@') { + pr_info("Video resolution for VGA interface not provided, using default\n"); + } else { + /* Check string to see if its one of the configurations we alaredy have... + * and if not, pass it as mode string, just in case we want to use one + * of the standard video configurations + */ + if ((panel = ccwmx51_find_video_config(vga_panel_list, + ARRAY_SIZE(vga_panel_list), + p)) != NULL) { + pr_info("Panel: %s", p); + memcpy(&mx51_fb_data[i], + &plcd_platform_data[i].fb_pdata, + sizeof(struct mxc_fb_platform_data)); + } else { + /* Pass the video configuration as mode string */ + pr_info("VGA: string %s", p); + + if (!strcmp(p, "800x600")) { + strcpy(mx51_fb_data[0].mode_str, "VGA@800x600M-32"); + } else if (!strcmp(p, "1280x1024")) { + strcpy(mx51_fb_data[0].mode_str, "VGA@1280x1024M-32"); + } else { + strcpy(mx51_fb_data[0].mode_str, mstr); + } + } + } + } + mxc_fb_devices[i].num_resources = 1; + mxc_fb_devices[i].resource = &mxcfb_resources[i]; + mxc_register_device(&mxc_fb_devices[i], &mx51_fb_data[i]); + } + + /* DI0/1 DP-FG channel, used by the VPU */ + mxc_register_device(&mxc_fb_devices[2], NULL); + + return 0; +} +#endif + +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) +extern void gpio_ata_active(void); +extern void gpio_ata_inactive(void); + +static int ccwmx51_init_ata(struct platform_device *pdev) +{ + gpio_ata_active(); + return 0; +} + +static void ccwmx51_deinit_ata(void) +{ + gpio_ata_inactive(); +} + +struct fsl_ata_platform_data ata_data = { +#ifndef CONFIG_PATA_FSL_DISABLE_DMA + .udma_mask = ATA_UDMA3, + .mwdma_mask = ATA_MWDMA2, +#endif + .pio_mask = ATA_PIO4, + .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2, + .max_sg = MXC_IDE_DMA_BD_NR, + .init = ccwmx51_init_ata, + .exit = ccwmx51_deinit_ata, + .core_reg = NULL, + .io_reg = NULL, +}; #endif -void __init ccwmx51_init_devices ( void ) +void ccwmx51_init_devices(void) { #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) ccwmx51_init_ext_eth_mac(); diff --git a/arch/arm/mach-mx5/devices_ccwmx51.h b/arch/arm/mach-mx5/devices_ccwmx51.h index 7208099b6e2d..672bee19a123 100644 --- a/arch/arm/mach-mx5/devices_ccwmx51.h +++ b/arch/arm/mach-mx5/devices_ccwmx51.h @@ -33,12 +33,19 @@ extern struct platform_pwm_backlight_data mxc_pwm_backlight_data; extern struct mxc_audio_platform_data wm8753_data; extern struct mxc_fb_platform_data mx51_fb_data[]; extern struct uio_info gpu2d_platform_data; -extern struct ccwmx51_lcd_pdata * plcd_platform_data; +extern struct ccwmx51_lcd_pdata plcd_platform_data[2]; +extern struct fsl_ata_platform_data ata_data; extern int __init ccwmx51_init_i2c2(void); extern void ccwmx51_init_spidevices(void); extern int __init ccwmx51_init_fb(void); extern void __init ccwmx51_io_init(void); extern int __init ccwmx51_init_mc13892(void); extern struct platform_device smsc911x_device; +extern void ccwmx51_set_mod_variant(u8 variant); +extern void ccwmx51_set_mod_revision(u8 revision); +extern void ccwmx51_set_mod_sn(u32 sn); +extern void ccwmx51_register_sdio(int interface); +extern void ccwmx51_init_devices(void); +extern int ccwmx51_create_sysfs_entries(void); #endif /* DEVICES_CCWMX51_H_ */ diff --git a/arch/arm/mach-mx5/displays/displays.h b/arch/arm/mach-mx5/displays/displays.h index 1fa2c1d05b5d..d738781a31e2 100644 --- a/arch/arm/mach-mx5/displays/displays.h +++ b/arch/arm/mach-mx5/displays/displays.h @@ -1,7 +1,7 @@ /* - * arch/arm/mach-s3c2443/displays/displays.h + * arch/arm/mach-mx5/displays/displays.h * - * Copyright (C) 2009 by Digi International Inc. + * Copyright (C) 2009-2010 by Digi International Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -12,20 +12,17 @@ #ifndef __ASM_ARCH_MXC_CCWMX51_DISPLAYS_H__ #define __ASM_ARCH_MXC_CCWMX51_DISPLAYS_H__ -#if defined(CONFIG_CCWMX51_LQ070Y3DG3B) -#include "LQ070Y3DG3B.h" -#endif -#if defined(CONFIG_CCWMX51_CUSTOM) -#include "CUSTOM.h" -#endif +extern void gpio_video_active(int vif, u32 pad); +extern void gpio_video_inactive(int vif); -struct ccwmx51_lcd_pdata lcd_display_list[] = { -#if defined(CONFIG_CCWMX51_LQ070Y3DG3B) - LQ070Y3DG3B_DISPLAY, +#ifdef CONFIG_CCWMX51_DISP0_RGB888 +#define VIDEO_PIX_FMT IPU_PIX_FMT_RGB24 +#else +#define VIDEO_PIX_FMT IPU_PIX_FMT_RGB666 #endif -#if defined(CONFIG_CCWMX51_CUSTOM) - CUSTOM_DISPLAY, -#endif -}; + +#include "hdmi_ad9389.h" +#include "vga.h" +#include "lcd.h" #endif /* __ASM_ARCH_MXC_CCWMX51_DISPLAYS_H__ */ diff --git a/arch/arm/mach-mx5/displays/hdmi_ad9389.h b/arch/arm/mach-mx5/displays/hdmi_ad9389.h new file mode 100644 index 000000000000..b800fca3e9ff --- /dev/null +++ b/arch/arm/mach-mx5/displays/hdmi_ad9389.h @@ -0,0 +1,172 @@ +/* + * arch/arm/mach-mx5/displays/hdmi_ad9389.h + * + * Copyright (C) 2010 by Digi International 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. + */ + +#ifndef __ASM_ARCH_MXC_CCWMX51_DISPLAYS_HDMI_AD9389_H__ +#define __ASM_ARCH_MXC_CCWMX51_DISPLAYS_HDMI_AD9389_H__ + +static struct fb_videomode ad9389_1280x720x24 = { + .name = "1280x720", + .refresh = 60, + .xres = 1280, + .yres = 720, + .pixclock = 20100, + .left_margin = 32, + .right_margin = 48, + .upper_margin = 7, + .lower_margin = 3, + .hsync_len = 32, + .vsync_len = 6, + .sync = FB_SYNC_CLK_LAT_FALL, +}; + +static struct fb_videomode ad9389_1360x768x24 = { + .name = "1360x768", + .refresh = 60, + .xres = 1360, + .yres = 768, + .pixclock = 16000, + .left_margin = 139, + .right_margin = 256, + .upper_margin = 3, + .lower_margin = 18, + .hsync_len = 76, + .vsync_len = 6, + .sync = FB_SYNC_CLK_LAT_FALL, +}; + + +static struct fb_videomode ad9389_1366x768x24 = { + .name = "1366x768", + .refresh = 60, + .xres = 1366, + .yres = 768, + .pixclock = 16000, + .left_margin = 139, + .right_margin = 256, + .upper_margin = 3, + .lower_margin = 18, + .hsync_len = 76, + .vsync_len = 6, + .sync = FB_SYNC_CLK_LAT_FALL, +}; + +static struct fb_videomode ad9389_1920x1080x24 = { + .name = "1920x1080", + .refresh = 60, + .xres = 1920, + .yres = 1080, + .pixclock = 7560, + .left_margin = 148, + .right_margin = 88, + .upper_margin = 36, + .lower_margin = 4, + .hsync_len = 44, + .vsync_len = 5, + .sync = 0, +}; + +static struct fb_videomode ad9389_1024x768x24 = { + .name = "1024x768", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15384, /* pico seconds of 65.0MHz */ + .left_margin = 160, + .right_margin = 24, + .upper_margin = 29, + .lower_margin = 3, + .hsync_len = 136, + .vsync_len = 6, +}; + +static struct fb_videomode ad9389_custom_1 = { + .name = "custom1", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .sync = 0, +}; + +static struct fb_videomode ad9389_custom_2 = { + .name = "custom2", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .sync = 0, +}; + +struct ccwmx51_lcd_pdata ad9389_panel_list[] = { + { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1280x720", + .mode = &ad9389_1280x720x24, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1360x768", + .mode = &ad9389_1360x768x24, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1366x768", + .mode = &ad9389_1366x768x24, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1920x1080", + .mode = &ad9389_1920x1080x24, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1024x768", + .mode = &ad9389_1024x768x24, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom1", + .mode = &ad9389_custom_1, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom2", + .mode = &ad9389_custom_2, + }, + .bl_enable = NULL, + }, +}; +#endif /* __ASM_ARCH_MXC_CCWMX51_DISPLAYS_HDMI_AD9389_H__ */
\ No newline at end of file diff --git a/arch/arm/mach-mx5/displays/lcd.h b/arch/arm/mach-mx5/displays/lcd.h new file mode 100644 index 000000000000..f2af740ebf85 --- /dev/null +++ b/arch/arm/mach-mx5/displays/lcd.h @@ -0,0 +1,135 @@ +/* + * arch/arm/mach-mx5/displays/lcd.h + * + * Copyright (C) 2010 by Digi International 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. + */ + +#ifndef __ASM_ARCH_MXC_CCWMX51_DISPLAYS_LCD_H__ +#define __ASM_ARCH_MXC_CCWMX51_DISPLAYS_LCD_H__ + +#include "../iomux.h" + +#if defined (CONFIG_JSCCWMX51_V1) +#include "../drivers/mxc/ipu3/ipu_regs.h" + +/** + * This code is only valide to enable/disable the backlight of the second + * display, on the first version of the JumpStart Board (JSCCWMX51 RevA). + * Newer versions use a GPIO to enable the BL of the second display. + */ +void ipu_ccwmx51_disp1_enable(int enable) +{ + uint32_t tmp; + + tmp = __raw_readl(DI_GENERAL(1)); + tmp &= ~DI_GEN_POLARITY_4; + if (enable) + tmp |= DI_GEN_POLARITY_4; + __raw_writel(tmp, DI_GENERAL(1)); +} +#endif + +static void lcd_bl_enable_lq70(int enable, int vif) +{ + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), !enable); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN12), !enable); + if (vif == 0) + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), !enable); + else if (vif == 1) +#ifdef CONFIG_JSCCWMX51_V1 + ipu_ccwmx51_disp1_enable(enable); +#elif defined(CONFIG_JSCCWMX51_V2) + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN12), !enable); +#else +#error "A function to enable/disalbe the display have to be specified" +#endif +} + +static void lcd_init(int vif) +{ + /* Initialize lcd enable gpio and video interface lines */ + gpio_video_active(vif, PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); +} + +static struct fb_videomode lq70y3dg3b = { + .name = "LQ070Y3DG3B", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = 44000, + .left_margin = 0, + .right_margin = 50, + .upper_margin = 25, + .lower_margin = 10, + .hsync_len = 128, + .vsync_len = 10, + .vmode = FB_VMODE_NONINTERLACED, + .sync = FB_SYNC_EXT, + .flag = 0, +}; + +static struct fb_videomode lcd_custom_1 = { + .name = "custom1", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .vmode = FB_VMODE_NONINTERLACED, + .sync = FB_SYNC_EXT, +}; + +static struct fb_videomode lcd_custom_2 = { + .name = "custom2", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .vmode = FB_VMODE_NONINTERLACED, + .sync = FB_SYNC_EXT, +}; + +struct ccwmx51_lcd_pdata lcd_panel_list[] = { + { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "LQ070Y3DG3B", + .mode = &lq70y3dg3b, + }, + .bl_enable = lcd_bl_enable_lq70, + .init = &lcd_init, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom1", + .mode = &lcd_custom_1, + }, + .bl_enable = NULL, + .init = &lcd_init, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom2", + .mode = &lcd_custom_2, + }, + .bl_enable = NULL, + .init = &lcd_init, + }, +}; +#endif /* __ASM_ARCH_MXC_CCWMX51_DISPLAYS_LCD_H__ */ diff --git a/arch/arm/mach-mx5/displays/vga.h b/arch/arm/mach-mx5/displays/vga.h new file mode 100644 index 000000000000..3e5a913c643a --- /dev/null +++ b/arch/arm/mach-mx5/displays/vga.h @@ -0,0 +1,64 @@ +/* + * arch/arm/mach-mx5/displays/vga.h + * + * Copyright (C) 2010 by Digi International 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. + */ + +#ifndef __ASM_ARCH_MXC_CCWMX51_DISPLAYS_VGA_H__ +#define __ASM_ARCH_MXC_CCWMX51_DISPLAYS_VGA_H__ + +static struct fb_videomode vga_custom_1 = { + .name = "custom1", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .vmode = FB_VMODE_NONINTERLACED, + .sync = FB_SYNC_EXT, +}; + +static struct fb_videomode vga_custom_2 = { + .name = "custom1", + .refresh = 0, + .xres = 0, + .yres = 0, + .pixclock = 0, + .left_margin = 0, + .right_margin = 0, + .upper_margin = 0, + .lower_margin = 0, + .hsync_len = 0, + .vsync_len = 0, + .vmode = FB_VMODE_NONINTERLACED, + .sync = FB_SYNC_EXT, +}; + +struct ccwmx51_lcd_pdata vga_panel_list[] = { + { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom1", + .mode = &vga_custom_1, + }, + .bl_enable = NULL, + }, { + .fb_pdata = { + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "custom2", + .mode = &vga_custom_2, + }, + .bl_enable = NULL, + }, +}; +#endif /* __ASM_ARCH_MXC_CCWMX51_DISPLAYS_VGA_H__ */
\ No newline at end of file diff --git a/arch/arm/mach-mx5/dma.c b/arch/arm/mach-mx5/dma.c index b79fab73e41f..39b7776c6d15 100644 --- a/arch/arm/mach-mx5/dma.c +++ b/arch/arm/mach-mx5/dma.c @@ -13,11 +13,14 @@ #include <linux/init.h> #include <linux/device.h> #include <asm/dma.h> +#include <mach/dma.h> #include <mach/hardware.h> +#include <mach/mxc_uart.h> #include "serial.h" #include "sdma_script_code.h" #include "sdma_script_code_mx53.h" +#include "sdma_script_code_mx50.h" #define MXC_MMC_BUFFER_ACCESS 0x20 #define MXC_SDHC_MMC_WML 64 @@ -1344,16 +1347,82 @@ static void __init mx53_sdma_get_script_info(sdma_script_start_addrs *sdma_scrip sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; /* core */ - sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code; + sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code_mx53; sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR_MX53; sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE_MX53; } +static void __init mx50_sdma_get_script_info(sdma_script_start_addrs *sdma_script_addr) +{ + /* AP<->BP */ + sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR_MX50; + sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1; + sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1; + sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr = -1; + + /*misc */ + sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; + sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; + + /* firi */ + sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; + sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1; + + /* uart */ + sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_mcu_ADDR_MX50; + sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR_MX50; + + /* UART SH */ + sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_mcu_ADDR_MX50; + sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR_MX50; + + /* SHP */ + sdma_script_addr->mxc_sdma_per_2_shp_addr = mcu_2_shp_ADDR_MX50; + sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_mcu_ADDR_MX50; + sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR_MX50; + sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR_MX50; + + /* ATA use it's own DMA */ + sdma_script_addr->mxc_sdma_mcu_2_ata_addr = -1; + sdma_script_addr->mxc_sdma_ata_2_mcu_addr = -1; + + /* app */ + sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_mcu_ADDR_MX50; + sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR_MX50; + sdma_script_addr->mxc_sdma_per_2_app_addr = mcu_2_app_ADDR_MX50; + sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR_MX50; + + /* MSHC */ + sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1; + + /* spdif */ + sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = -1; + + sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = -1; + + /* IPU */ + sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = -1; + + /* DVFS */ + sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; + + /* core */ + sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code_mx50; + sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR_MX50; + sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE_MX50; +} + void __init mxc_sdma_get_script_info(sdma_script_start_addrs *sdma_script_addr) { if (cpu_is_mx51()) mx51_sdma_get_script_info(sdma_script_addr); - else + else if (cpu_is_mx53()) mx53_sdma_get_script_info(sdma_script_addr); + else + mx50_sdma_get_script_info(sdma_script_addr); } diff --git a/arch/arm/mach-mx5/dummy_gpio.c b/arch/arm/mach-mx5/dummy_gpio.c index 8eb771d29a06..9d4cd07d28f9 100644 --- a/arch/arm/mach-mx5/dummy_gpio.c +++ b/arch/arm/mach-mx5/dummy_gpio.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2007-2010 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -53,12 +53,6 @@ EXPORT_SYMBOL(gpio_pmic_active); void gpio_activate_audio_ports(void) {} EXPORT_SYMBOL(gpio_activate_audio_ports); -void gpio_sdhc_active(int module) {} -EXPORT_SYMBOL(gpio_sdhc_active); - -void gpio_sdhc_inactive(int module) {} -EXPORT_SYMBOL(gpio_sdhc_inactive); - void gpio_sensor_select(int sensor) {} void gpio_sensor_active(unsigned int csi) {} @@ -67,12 +61,6 @@ EXPORT_SYMBOL(gpio_sensor_active); void gpio_sensor_inactive(unsigned int csi) {} EXPORT_SYMBOL(gpio_sensor_inactive); -void gpio_ata_active(void) {} -EXPORT_SYMBOL(gpio_ata_active); - -void gpio_ata_inactive(void) {} -EXPORT_SYMBOL(gpio_ata_inactive); - void gpio_nand_active(void) {} EXPORT_SYMBOL(gpio_nand_active); @@ -105,3 +93,9 @@ EXPORT_SYMBOL(gpio_spdif_active); void gpio_spdif_inactive(void) {} EXPORT_SYMBOL(gpio_spdif_inactive); + +void gpio_mlb_active(void) {} +EXPORT_SYMBOL(gpio_mlb_active); + +void gpio_mlb_inactive(void) {} +EXPORT_SYMBOL(gpio_mlb_inactive); diff --git a/arch/arm/mach-mx5/early_setup.c b/arch/arm/mach-mx5/early_setup.c new file mode 100644 index 000000000000..dd731d7f822e --- /dev/null +++ b/arch/arm/mach-mx5/early_setup.c @@ -0,0 +1,29 @@ +/* + * 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/string.h> + +int __initdata primary_di = { 0 }; +static int __init di_setup(char *__unused) +{ + primary_di = 1; + return 1; +} +__setup("di1_primary", di_setup); + diff --git a/arch/arm/mach-mx5/iomux.c b/arch/arm/mach-mx5/iomux.c index 319980ad176a..4cca66447443 100644 --- a/arch/arm/mach-mx5/iomux.c +++ b/arch/arm/mach-mx5/iomux.c @@ -37,6 +37,9 @@ #define INPUT_CTL_START_MX53 0x730 #define MUX_I_END_MX53 (PAD_I_START_MX53 - 4) +#define PAD_I_START_MX50 0x2CC +#define INPUT_CTL_START_MX50 0x6C4 + /*! * IOMUX register (base) addressesf */ @@ -52,8 +55,10 @@ static inline void *_get_sw_pad(void) { if (cpu_is_mx51()) return IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START_MX51; - else + else if (cpu_is_mx53()) return IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START_MX53; + else + return IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START_MX50; } static inline void * _get_mux_reg(iomux_pin_name_t pin) @@ -102,6 +107,9 @@ static inline void * _get_pad_reg(iomux_pin_name_t pin) static inline void * _get_mux_end(void) { + if (cpu_is_mx50()) + return IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x2C8; + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) return(IO_ADDRESS(IOMUXC_BASE_ADDR) + (0x3F8 - 4)); else @@ -264,8 +272,10 @@ void mxc_iomux_set_input(iomux_input_select_t input, u32 config) reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX51_TO1; } else if (cpu_is_mx51()) { reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX51; - } else + } else if (cpu_is_mx53()) { reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX53; + } else + reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX50; BUG_ON(input >= MUX_INPUT_NUM_MUX); __raw_writel(config, reg); diff --git a/arch/arm/mach-mx5/lpmodes.c b/arch/arm/mach-mx5/lpmodes.c index 32af9ccc4f6a..c9d770231b54 100644 --- a/arch/arm/mach-mx5/lpmodes.c +++ b/arch/arm/mach-mx5/lpmodes.c @@ -37,7 +37,6 @@ #include <mach/clock.h> #include <mach/hardware.h> #include <linux/regulator/machine.h> -#include "crm_regs.h" #define ARM_LP_CLK 166250000 #define GP_LPM_VOLTAGE 775000 diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index 8ac23c100bd9..575c49830989 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -61,7 +61,7 @@ void __init mx5_map_io(void) int i; /* Fixup the mappings for MX53 */ - if (cpu_is_mx53()) { + if (cpu_is_mx53() || cpu_is_mx50()) { for (i = 0; i < ARRAY_SIZE(mx5_io_desc); i++) mx5_io_desc[i].pfn -= __phys_to_pfn(0x20000000); } diff --git a/arch/arm/mach-mx5/mx50_arm2.c b/arch/arm/mach-mx5/mx50_arm2.c new file mode 100644 index 000000000000..3a4e8dc3e923 --- /dev/null +++ b/arch/arm/mach-mx5/mx50_arm2.c @@ -0,0 +1,559 @@ +/* + * 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/types.h> +#include <linux/sched.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/nodemask.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/fsl_devices.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/ata.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/machine.h> +#include <linux/regulator/max17135.h> +#include <linux/pmic_external.h> +#include <linux/pmic_status.h> +#include <linux/videodev2.h> +#include <linux/mxcfb.h> +#include <linux/fec.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 <asm/mach/flash.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/memory.h> +#include <mach/gpio.h> +#include <mach/mmc.h> +#include <mach/mxc_dvfs.h> +#include "iomux.h" +#include "mx50_pins.h" +#include "devices.h" +#include "usb.h" + +extern void __init mx50_arm2_io_init(void); +extern int __init mx50_arm2_init_mc13892(void); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +extern void (*set_num_cpu_wp)(int num); +static int num_cpu_wp = 3; + +/* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */ +static struct cpu_wp cpu_wp_auto[] = { + { + .pll_rate = 1000000000, + .cpu_rate = 1000000000, + .pdf = 0, + .mfi = 10, + .mfd = 11, + .mfn = 5, + .cpu_podf = 0, + .cpu_voltage = 1175000,}, + { + .pll_rate = 800000000, + .cpu_rate = 800000000, + .pdf = 0, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 0, + .cpu_voltage = 1100000,}, + { + .pll_rate = 800000000, + .cpu_rate = 166250000, + .pdf = 4, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 4, + .cpu_voltage = 850000,}, +}; + +static struct cpu_wp *mx50_arm2_get_cpu_wp(int *wp) +{ + *wp = num_cpu_wp; + return cpu_wp_auto; +} + +static void mx50_arm2_set_num_cpu_wp(int num) +{ + num_cpu_wp = num; + return; +} + +static struct mxc_w1_config mxc_w1_data = { + .search_rom_accelerator = 1, +}; + +static struct fec_platform_data fec_data = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +extern void mx50_arm2_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect); +extern void mx50_arm2_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect); +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 4, + .spi_version = 23, + .chipselect_active = mx50_arm2_gpio_spi_chipselect_active, + .chipselect_inactive = mx50_arm2_gpio_spi_chipselect_inactive, +}; + +static struct mxc_spi_master mxcspi3_data = { + .maxchipselect = 4, + .spi_version = 7, + .chipselect_active = mx50_arm2_gpio_spi_chipselect_active, + .chipselect_inactive = mx50_arm2_gpio_spi_chipselect_inactive, +}; + +static struct mxc_i2c_platform_data mxci2c_data = { + .i2c_clk = 100000, +}; + +static struct mxc_srtc_platform_data srtc_data = { + .srtc_sec_mode_addr = OCOTP_CTRL_BASE_ADDR + 0x80, +}; + +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +static struct regulator_init_data max17135_init_data[] __initdata = { + { + .constraints = { + .name = "DISPLAY", + }, + }, { + .constraints = { + .name = "GVDD", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "GVEE", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINN", + .min_uV = V_to_uV(-22), + .max_uV = V_to_uV(-22), + }, + }, { + .constraints = { + .name = "HVINP", + .min_uV = V_to_uV(20), + .max_uV = V_to_uV(20), + }, + }, { + .constraints = { + .name = "VCOM", + .min_uV = mV_to_uV(-4325), + .max_uV = mV_to_uV(-500), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + }, { + .constraints = { + .name = "VNEG", + .min_uV = V_to_uV(-15), + .max_uV = V_to_uV(-15), + }, + }, { + .constraints = { + .name = "VPOS", + .min_uV = V_to_uV(15), + .max_uV = V_to_uV(15), + }, + }, +}; + +static struct max17135_platform_data max17135_pdata = { + .vneg_pwrup = 1, + .gvee_pwrup = 1, + .vpos_pwrup = 2, + .gvdd_pwrup = 1, + .gvdd_pwrdn = 1, + .vpos_pwrdn = 2, + .gvee_pwrdn = 1, + .vneg_pwrdn = 1, + .gpio_pmic_pwrgood = IOMUX_TO_GPIO(MX50_PIN_EPDC_PWRSTAT), + .gpio_pmic_vcom_ctrl = IOMUX_TO_GPIO(MX50_PIN_EPDC_VCOM0), + .gpio_pmic_wakeup = IOMUX_TO_GPIO(MX50_PIN_UART4_TXD), + .gpio_pmic_intr = IOMUX_TO_GPIO(MX50_PIN_UART4_RXD), + .regulator_init = max17135_init_data, +}; + +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { + { + .type = "sgtl5000-i2c", + .addr = 0x0a, + }, + { + .type = "backlight-i2c", + .addr = 0x2c, + }, + { + .type = "eeprom", + .addr = 0x50, + }, +}; + +static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { + { + I2C_BOARD_INFO("max17135", 0x48), + .platform_data = &max17135_pdata, + }, +}; + +static struct mtd_partition mxc_dataflash_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x000100000,}, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL,}, +}; + +static struct flash_platform_data mxc_spi_flash_data[] = { + { + .name = "mxc_dataflash", + .parts = mxc_dataflash_partitions, + .nr_parts = ARRAY_SIZE(mxc_dataflash_partitions), + .type = "at45db321d",} +}; + + +static struct spi_board_info mxc_dataflash_device[] __initdata = { + { + .modalias = "mxc_dataflash", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 3, + .chip_select = 1, + .platform_data = &mxc_spi_flash_data[0],}, +}; + +static int sdhc_write_protect(struct device *dev) +{ + unsigned short rc = 0; + + if (to_platform_device(dev)->id == 0) + rc = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_ECSPI2_SS0)); + else if (to_platform_device(dev)->id == 1) + rc = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_SD2_WP)); + else if (to_platform_device(dev)->id == 2) + rc = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_SD3_WP)); + + return rc; +} + +static unsigned int sdhc_get_card_det_status(struct device *dev) +{ + int ret; + if (to_platform_device(dev)->id == 0) + ret = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_EIM_CRE)); + else if (to_platform_device(dev)->id == 1) + ret = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_SD2_CD)); + else if (to_platform_device(dev)->id == 2) + ret = gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_KEY_COL2)); + + return ret; +} + +static struct mxc_mmc_platform_data mmc1_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 + | MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA, + .min_clk = 400000, + .max_clk = 50000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", + .power_mmc = NULL, +}; + +static struct mxc_mmc_platform_data mmc2_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 + | MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .min_clk = 400000, + .max_clk = 50000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", +}; + +static struct mxc_mmc_platform_data mmc3_data = { + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 + | MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .min_clk = 400000, + .max_clk = 50000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", +}; + +static int mxc_sgtl5000_amp_enable(int enable) +{ +/* TO DO */ + return 0; +} + +static int headphone_det_status(void) +{ + return (gpio_get_value(IOMUX_TO_GPIO(MX50_PIN_ECSPI1_SS0)) != 0); +} + +static struct mxc_audio_platform_data sgtl5000_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_irq = IOMUX_TO_IRQ(MX50_PIN_ECSPI1_SS0), + .hp_status = headphone_det_status, + .amp_enable = mxc_sgtl5000_amp_enable, + .sysclk = 12288000, +}; + +static struct platform_device mxc_sgtl5000_device = { + .name = "imx-3stack-sgtl5000", +}; + +static void wvga_reset(void) +{ + /* ELCDIF D0 */ + mxc_free_iomux(MX50_PIN_DISP_D0, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D0, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D0, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D1 */ + mxc_free_iomux(MX50_PIN_DISP_D1, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D1, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D1, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D2 */ + mxc_free_iomux(MX50_PIN_DISP_D2, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D2, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D2, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D3 */ + mxc_free_iomux(MX50_PIN_DISP_D3, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D3, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D3, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D4 */ + mxc_free_iomux(MX50_PIN_DISP_D4, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D4, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D4, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D5 */ + mxc_free_iomux(MX50_PIN_DISP_D5, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D5, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D5, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D6 */ + mxc_free_iomux(MX50_PIN_DISP_D6, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D6, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D6, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + /* ELCDIF D7 */ + mxc_free_iomux(MX50_PIN_DISP_D7, IOMUX_CONFIG_ALT2); + mxc_request_iomux(MX50_PIN_DISP_D7, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_DISP_D7, PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_DRV_HIGH); + return; +} + +static struct mxc_lcd_platform_data lcd_wvga_data = { + .reset = wvga_reset, +}; + +static struct platform_device lcd_wvga_device = { + .name = "lcd_claa", + .dev = { + .platform_data = &lcd_wvga_data, + }, +}; + +static struct fb_videomode video_modes[] = { + { + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */ + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, +}; + +static struct mxc_fb_platform_data fb_data[] = { + { + .interface_pix_fmt = V4L2_PIX_FMT_RGB565, + .mode_str = "CLAA-WVGA", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), + }, +}; + +/*! + * Board specific fixup function. It is called by \b setup_arch() in + * setup.c file very early on during kernel starts. It allows the user to + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mxc_set_cpu_type(MXC_CPU_MX50); + + get_cpu_wp = mx50_arm2_get_cpu_wp; + set_num_cpu_wp = mx50_arm2_set_num_cpu_wp; +} + +/*! + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + /* SD card detect irqs */ + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX50_PIN_EIM_CRE); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX50_PIN_EIM_CRE); + mxcsdhc2_device.resource[2].start = IOMUX_TO_IRQ(MX50_PIN_SD2_CD); + mxcsdhc2_device.resource[2].end = IOMUX_TO_IRQ(MX50_PIN_SD2_CD); + mxcsdhc3_device.resource[2].start = IOMUX_TO_IRQ(MX50_PIN_KEY_COL2); + mxcsdhc3_device.resource[2].end = IOMUX_TO_IRQ(MX50_PIN_KEY_COL2); + + mxc_cpu_common_init(); + mxc_register_gpios(); + mx50_arm2_io_init(); + + mxc_register_device(&mxc_dma_device, NULL); + mxc_register_device(&mxc_wdt_device, NULL); + mxc_register_device(&mxcspi1_device, &mxcspi1_data); + mxc_register_device(&mxcspi3_device, &mxcspi3_data); + mxc_register_device(&mxci2c_devices[0], &mxci2c_data); + mxc_register_device(&mxci2c_devices[1], &mxci2c_data); + mxc_register_device(&mxci2c_devices[2], &mxci2c_data); + + mxc_register_device(&mxc_rtc_device, &srtc_data); + mxc_register_device(&mxc_w1_master_device, &mxc_w1_data); + mxc_register_device(&gpu_device, NULL); + mxc_register_device(&mxc_pxp_device, NULL); + mxc_register_device(&mxc_pxp_client_device, NULL); + /* + mxc_register_device(&mx53_lpmode_device, NULL); + mxc_register_device(&busfreq_device, NULL); + mxc_register_device(&mxc_dvfs_core_device, &dvfs_core_data); + mxc_register_device(&mxc_dvfs_per_device, &dvfs_per_data); + */ + +/* mxc_register_device(&mxc_keypad_device, &keypad_plat_data); */ + + mxc_register_device(&mxcsdhc1_device, &mmc1_data); + mxc_register_device(&mxcsdhc2_device, &mmc2_data); + mxc_register_device(&mxcsdhc3_device, &mmc3_data); + mxc_register_device(&mxc_ssi1_device, NULL); + mxc_register_device(&mxc_ssi2_device, NULL); + mxc_register_device(&mxc_fec_device, &fec_data); + spi_register_board_info(mxc_dataflash_device, + ARRAY_SIZE(mxc_dataflash_device)); + i2c_register_board_info(1, mxc_i2c1_board_info, + ARRAY_SIZE(mxc_i2c1_board_info)); + i2c_register_board_info(2, mxc_i2c2_board_info, + ARRAY_SIZE(mxc_i2c2_board_info)); + + mxc_register_device(&epdc_device, NULL); + mxc_register_device(&lcd_wvga_device, &lcd_wvga_data); + mxc_register_device(&elcdif_device, &fb_data[0]); + + mx50_arm2_init_mc13892(); +/* + pm_power_off = mxc_power_off; + */ + mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data); + mx5_usb_dr_init(); + mx5_usbh1_init(); +} + +static void __init mx50_arm2_timer_init(void) +{ + struct clk *uart_clk; + + mx50_clocks_init(32768, 24000000, 22579200); + + uart_clk = clk_get(NULL, "uart_clk.0"); + early_console_setup(MX53_BASE_ADDR(UART1_BASE_ADDR), uart_clk); +} + +static struct sys_timer mxc_timer = { + .init = mx50_arm2_timer_init, +}; + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX50_ARM2 data structure. + */ +MACHINE_START(MX50_ARM2, "Freescale MX50 ARM2 Board") + /* Maintainer: Freescale Semiconductor, Inc. */ + .fixup = fixup_mxc_board, + .map_io = mx5_map_io, + .init_irq = mx5_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/mx50_arm2_gpio.c b/arch/arm/mach-mx5/mx50_arm2_gpio.c new file mode 100644 index 000000000000..8b37784ef9b5 --- /dev/null +++ b/arch/arm/mach-mx5/mx50_arm2_gpio.c @@ -0,0 +1,658 @@ +/* + * 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/errno.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include <mach/gpio.h> + +#include "iomux.h" +#include "mx50_pins.h" + +/*! + * @file mach-mx5/mx50_arm2_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO + */ + +static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { + { /* SD1 WP */ + MX50_PIN_ECSPI2_SS0, IOMUX_CONFIG_GPIO, + }, + { /* SD1 CD */ + MX50_PIN_EIM_CRE, IOMUX_CONFIG_GPIO, + }, + { /* SD1 CMD */ + MX50_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD1 CLK */ + MX50_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD1 D0 */ + MX50_PIN_SD1_D0, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD1 D1 */ + MX50_PIN_SD1_D1, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD1 D2 */ + MX50_PIN_SD1_D2, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD1 D3 */ + MX50_PIN_SD1_D3, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 CD */ + MX50_PIN_SD2_CD, IOMUX_CONFIG_GPIO, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 WP */ + MX50_PIN_SD2_WP, IOMUX_CONFIG_GPIO, + }, + { /* SD2 CMD */ + MX50_PIN_SD2_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 CLK */ + MX50_PIN_SD2_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D0 */ + MX50_PIN_SD2_D0, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D1 */ + MX50_PIN_SD2_D1, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D2 */ + MX50_PIN_SD2_D2, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D3 */ + MX50_PIN_SD2_D3, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D4 */ + MX50_PIN_SD2_D4, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D5 */ + MX50_PIN_SD2_D5, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D6 */ + MX50_PIN_SD2_D6, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD2 D7 */ + MX50_PIN_SD2_D7, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD3 CD */ + MX50_PIN_KEY_COL2, IOMUX_CONFIG_GPIO, + (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + }, + { /* SD3 WP */ + MX50_PIN_SD3_WP, IOMUX_CONFIG_GPIO, + }, + { /* SD3 CMD */ + MX50_PIN_SD3_CMD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 CLK */ + MX50_PIN_SD3_CLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_47K_PU | + PAD_CTL_DRV_HIGH), + }, + { /* SD3 D0 */ + MX50_PIN_SD3_D0, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D1 */ + MX50_PIN_SD3_D1, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D2 */ + MX50_PIN_SD3_D2, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D3 */ + MX50_PIN_SD3_D3, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D4 */ + MX50_PIN_SD3_D4, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D5 */ + MX50_PIN_SD3_D5, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D6 */ + MX50_PIN_SD3_D6, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + { /* SD3 D7 */ + MX50_PIN_SD3_D7, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_47K_PU | PAD_CTL_DRV_HIGH), + }, + + { + MX50_PIN_SSI_TXD, IOMUX_CONFIG_ALT0, + }, + { + MX50_PIN_SSI_RXD, IOMUX_CONFIG_ALT0, + }, + { + MX50_PIN_SSI_TXC, IOMUX_CONFIG_ALT0, + }, + { + MX50_PIN_SSI_TXFS, IOMUX_CONFIG_ALT0, + }, + /* LINE1_DETECT (headphone detect) */ + { + MX50_PIN_ECSPI1_SS0, IOMUX_CONFIG_GPIO, PAD_CTL_100K_PU, + }, + { + MX50_PIN_ECSPI2_MISO, IOMUX_CONFIG_GPIO, PAD_CTL_100K_PU, + }, + /* UART pad setting */ + { + MX50_PIN_UART1_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { + MX50_PIN_UART1_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX50_PIN_UART1_CTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { + MX50_PIN_UART1_RTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX50_PIN_UART2_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { + MX50_PIN_UART2_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX50_PIN_UART2_CTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { + MX50_PIN_UART2_RTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { /* I2C1 SDA */ + MX50_PIN_I2C1_SDA, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + { /* I2C1 SCL */ + MX50_PIN_I2C1_SCL, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + { /* I2C2 SDA */ + MX50_PIN_I2C2_SDA, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + { /* I2C2 SCL */ + MX50_PIN_I2C2_SCL, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + { /* I2C3 SDA */ + MX50_PIN_I2C3_SDA, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + { /* I2C3 SCL */ + MX50_PIN_I2C3_SCL, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + }, + /* EPDC pins */ + { /* EPDC D0 */ + MX50_PIN_EPDC_D0, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D1 */ + MX50_PIN_EPDC_D1, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D2 */ + MX50_PIN_EPDC_D2, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D3 */ + MX50_PIN_EPDC_D3, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D4 */ + MX50_PIN_EPDC_D4, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D5 */ + MX50_PIN_EPDC_D5, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D6 */ + MX50_PIN_EPDC_D6, IOMUX_CONFIG_ALT0, + }, + { /* EPDC D7 */ + MX50_PIN_EPDC_D7, IOMUX_CONFIG_ALT0, + }, + { /* EPDC GDCLK */ + MX50_PIN_EPDC_GDCLK, IOMUX_CONFIG_ALT0, + }, + { /* EPDC GDSP */ + MX50_PIN_EPDC_GDSP, IOMUX_CONFIG_ALT0, + }, + { /* EPDC GDOE */ + MX50_PIN_EPDC_GDOE, IOMUX_CONFIG_ALT0, + }, + { /* EPDC GDRL */ + MX50_PIN_EPDC_GDRL, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDCLK */ + MX50_PIN_EPDC_SDCLK, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDOE */ + MX50_PIN_EPDC_SDOE, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDLE */ + MX50_PIN_EPDC_SDLE, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDSHR */ + MX50_PIN_EPDC_SDSHR, IOMUX_CONFIG_ALT0, + }, + { /* EPDC BDR0 */ + MX50_PIN_EPDC_BDR0, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDCE0 */ + MX50_PIN_EPDC_SDCE0, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDCE1 */ + MX50_PIN_EPDC_SDCE1, IOMUX_CONFIG_ALT0, + }, + { /* EPDC SDCE2 */ + MX50_PIN_EPDC_SDCE2, IOMUX_CONFIG_ALT0, + }, + /* EPD PMIC pins */ + { /* EPDC PWRSTAT - GPIO3[28] for PWR_GOOD status */ + MX50_PIN_EPDC_PWRSTAT, IOMUX_CONFIG_ALT1, + }, + { /* EPDC VCOM0 - GPIO4[21] for VCOM control */ + MX50_PIN_EPDC_VCOM0, IOMUX_CONFIG_ALT1, + }, + { /* ELCDIF D8 */ + MX50_PIN_DISP_D8, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D9 */ + MX50_PIN_DISP_D9, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D10 */ + MX50_PIN_DISP_D10, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D11 */ + MX50_PIN_DISP_D11, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D12 */ + MX50_PIN_DISP_D12, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D13 */ + MX50_PIN_DISP_D13, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D14 */ + MX50_PIN_DISP_D14, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF D15 */ + MX50_PIN_DISP_D15, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF VSYNC */ + MX50_PIN_DISP_RS, IOMUX_CONFIG_ALT2, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF contrast */ + MX50_PIN_DISP_BUSY, IOMUX_CONFIG_ALT1, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF HSYNC */ + MX50_PIN_DISP_CS, IOMUX_CONFIG_ALT2, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF DRDY */ + MX50_PIN_DISP_RD, IOMUX_CONFIG_ALT2, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* ELCDIF PIXCLK */ + MX50_PIN_DISP_WR, IOMUX_CONFIG_ALT2, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH), + }, + { /* UART4 TXD - GPIO6[16] for EPD PMIC WAKEUP */ + MX50_PIN_UART4_TXD, IOMUX_CONFIG_ALT1, + }, + { /* UART4 RXD - GPIO6[17] for EPD PMIC intr */ + MX50_PIN_UART4_RXD, IOMUX_CONFIG_ALT1, + }, + /* USB_H1_PWR */ + { + MX50_PIN_EPITO, IOMUX_CONFIG_ALT2, + PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH, + }, + /* FIXME: USB_H1_OC, need to comment below line if + * one needs to debug owire. + */ + { + MX50_PIN_OWIRE, IOMUX_CONFIG_ALT2, + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU, + }, + /* USB_OTG_PWR */ + { + MX50_PIN_PWM2, IOMUX_CONFIG_ALT2, + PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH, + }, + /* + * Set USB_OTG_OC, the pad value is the default value + * according to IC suggestion. + */ + { + MX50_PIN_PWM1, IOMUX_CONFIG_ALT2, + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU, + MUX_IN_USBOH1_IPP_IND_OTG_OC_SELECT_INPUT, INPUT_CTL_PATH1, + }, + { /* FEC_MDIO */ + MX50_PIN_SSI_RXC, IOMUX_CONFIG_ALT6, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_22K_PU | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH), + MUX_IN_FEC_FEC_MDI_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { /* FEC_TX_CLK */ + MX50_PIN_DISP_D0, IOMUX_CONFIG_ALT2, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /* FEC_RX_ER */ + MX50_PIN_DISP_D1, IOMUX_CONFIG_ALT2, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + MUX_IN_FEC_FEC_RX_ER_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* FEC_CRS_DV */ + MX50_PIN_DISP_D2, IOMUX_CONFIG_ALT2, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + MUX_IN_FEC_FEC_RX_DV_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* FEC_RXD1 */ + MX50_PIN_DISP_D3, IOMUX_CONFIG_ALT2, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + MUX_IN_FEC_FEC_RDATA_1_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* FEC_RXD0 */ + MX50_PIN_DISP_D4, IOMUX_CONFIG_ALT2, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + MUX_IN_FEC_FEC_RDATA_0_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* FEC_TX_EN */ + MX50_PIN_DISP_D5, IOMUX_CONFIG_ALT2, + PAD_CTL_DRV_HIGH, + }, + { /* FEC_TXD1 */ + MX50_PIN_DISP_D6, IOMUX_CONFIG_ALT2, + PAD_CTL_DRV_HIGH, + }, + { /* FEC_TXD0 */ + MX50_PIN_DISP_D7, IOMUX_CONFIG_ALT2, + PAD_CTL_DRV_HIGH, + }, + { /* FEC_MDC */ + MX50_PIN_SSI_RXFS, IOMUX_CONFIG_ALT6, + PAD_CTL_DRV_HIGH, + }, + { /* CSPI SS0 */ + MX50_PIN_CSPI_SS0, IOMUX_CONFIG_ALT0, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH), + }, + { /* CSPI SS1 */ + MX50_PIN_ECSPI1_MOSI, IOMUX_CONFIG_ALT2, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_22K_PU | PAD_CTL_DRV_HIGH), + }, + { + MX50_PIN_CSPI_MOSI, IOMUX_CONFIG_ALT0, + }, + { + MX50_PIN_CSPI_MISO, IOMUX_CONFIG_ALT0, + }, + { + MX50_PIN_CSPI_SCLK, IOMUX_CONFIG_ALT0, + }, +}; + +static int __initdata enable_w1 = { 0 }; +static int __init w1_setup(char *__unused) +{ + enable_w1 = 1; + return cpu_is_mx50(); +} + +__setup("w1", w1_setup); + +void __init mx50_arm2_io_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mxc_iomux_pins); i++) { + mxc_request_iomux(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].mux_mode); + if (mxc_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].pad_cfg); + if (mxc_iomux_pins[i].in_select) + mxc_iomux_set_input(mxc_iomux_pins[i].in_select, + mxc_iomux_pins[i].in_mode); + } + + /* SD1 WP */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_ECSPI2_SS0), "ecspi2_ss0"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_ECSPI2_SS0)); + + /* SD1 CD */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_EIM_CRE), "eim_cre"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_EIM_CRE)); + + /* SD2 WP */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_SD2_WP), "sd2_wp"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_SD2_WP)); + + /* SD2 CD */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_SD2_CD), "sd2_cd"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_SD2_CD)); + + /* SD3 WP */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_SD3_WP), "sd3_wp"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_SD2_WP)); + + /* SD3 CD */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_KEY_COL2), "key_col2"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_KEY_COL2)); + + /* LINE1_DETECT (headphone detect) */ + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_ECSPI1_SS0)); + + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_ECSPI2_MISO)); + + /* EPDC PMIC */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_UART4_TXD), "uart4_txd"); + gpio_direction_output(IOMUX_TO_GPIO(MX50_PIN_UART4_TXD), 0); + + gpio_request(IOMUX_TO_GPIO(MX50_PIN_EPDC_VCOM0), "epdc_vcom"); + gpio_direction_output(IOMUX_TO_GPIO(MX50_PIN_EPDC_VCOM0), 0); + + gpio_request(IOMUX_TO_GPIO(MX50_PIN_UART4_RXD), "uart4_rxd"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_UART4_RXD)); + + gpio_request(IOMUX_TO_GPIO(MX50_PIN_EPDC_PWRSTAT), "epdc_pwrstat"); + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_EPDC_PWRSTAT)); + + /* ELCDIF backlight */ + gpio_request(IOMUX_TO_GPIO(MX50_PIN_DISP_BUSY), "gp2_18"); + gpio_direction_output(IOMUX_TO_GPIO(MX50_PIN_DISP_BUSY), 1); + + if (enable_w1) { + /* OneWire */ + mxc_request_iomux(MX50_PIN_OWIRE, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX50_PIN_OWIRE, PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | + PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST | + PAD_CTL_100K_PU | + PAD_CTL_PUE_PULL); + } +} + +/* workaround for cspi chipselect pin may not keep correct level when idle */ +void mx50_arm2_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + break; + case 2: + break; + case 3: + switch (chipselect) { + case 0x1: + /* enable ss0 */ + mxc_request_iomux(MX50_PIN_CSPI_SS0, IOMUX_CONFIG_ALT0); + /*disable other ss */ + mxc_request_iomux(MX50_PIN_ECSPI1_MOSI, IOMUX_CONFIG_GPIO); + /* pull up/down deassert it */ + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_ECSPI1_MOSI)); + break; + case 0x2: + /* enable ss1 */ + mxc_request_iomux(MX50_PIN_ECSPI1_MOSI, IOMUX_CONFIG_ALT2); + /*disable other ss */ + mxc_request_iomux(MX50_PIN_CSPI_SS0, IOMUX_CONFIG_GPIO); + /* pull up/down deassert it */ + gpio_direction_input(IOMUX_TO_GPIO(MX50_PIN_CSPI_SS0)); + break; + default: + break; + } + break; + + default: + break; + } +} + +void mx50_arm2_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + break; + case 2: + break; + case 3: + switch (chipselect) { + case 0x1: + mxc_free_iomux(MX50_PIN_ECSPI1_MOSI, IOMUX_CONFIG_GPIO); + break; + case 0x2: + mxc_free_iomux(MX50_PIN_CSPI_SS0, IOMUX_CONFIG_GPIO); + break; + default: + break; + } + break; + default: + break; + } + +} diff --git a/arch/arm/mach-mx5/mx50_arm2_pmic_mc13892.c b/arch/arm/mach-mx5/mx50_arm2_pmic_mc13892.c new file mode 100644 index 000000000000..d852fb0e016b --- /dev/null +++ b/arch/arm/mach-mx5/mx50_arm2_pmic_mc13892.c @@ -0,0 +1,419 @@ +/* + * 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/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/err.h> +#include <linux/pmic_external.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/mc13892/core.h> +#include <mach/irqs.h> +#include "iomux.h" +#include "mx50_pins.h" + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +/* Coin cell charger enable */ +#define COINCHEN_LSH 23 +#define COINCHEN_WID 1 +/* Coin cell charger voltage setting */ +#define VCOIN_LSH 20 +#define VCOIN_WID 3 + +/* Coin Charger voltage */ +#define VCOIN_2_5V 0x0 +#define VCOIN_2_7V 0x1 +#define VCOIN_2_8V 0x2 +#define VCOIN_2_9V 0x3 +#define VCOIN_3_0V 0x4 +#define VCOIN_3_1V 0x5 +#define VCOIN_3_2V 0x6 +#define VCOIN_3_3V 0x7 + +/* Keeps VSRTC and CLK32KMCU on for all states */ +#define DRM_LSH 4 +#define DRM_WID 1 + +/* regulator standby mask */ +#define GEN1_STBY_MASK (1 << 1) +#define IOHI_STBY_MASK (1 << 4) +#define DIG_STBY_MASK (1 << 10) +#define GEN2_STBY_MASK (1 << 13) +#define PLL_STBY_MASK (1 << 16) +#define USB2_STBY_MASK (1 << 19) + +#define GEN3_STBY_MASK (1 << 1) +#define CAM_STBY_MASK (1 << 7) +#define VIDEO_STBY_MASK (1 << 13) +#define AUDIO_STBY_MASK (1 << 16) +#define SD_STBY_MASK (1 << 19) + +/* 0x92412 */ +#define REG_MODE_0_ALL_MASK (GEN1_STBY_MASK |\ + DIG_STBY_MASK | GEN2_STBY_MASK |\ + PLL_STBY_MASK) +/* 0x92082 */ +#define REG_MODE_1_ALL_MASK (CAM_STBY_MASK | VIDEO_STBY_MASK |\ + AUDIO_STBY_MASK | SD_STBY_MASK) + +/* switch mode setting */ +#define SW1MODE_LSB 0 +#define SW2MODE_LSB 10 +#define SW3MODE_LSB 0 +#define SW4MODE_LSB 8 + +#define SWMODE_MASK 0xF +#define SWMODE_AUTO 0x8 + +/* CPU */ +static struct regulator_consumer_supply sw1_consumers[] = { + { + .supply = "cpu_vcc", + } +}; + +static struct regulator_consumer_supply vgen1_consumers[] = { + { + /* sgtl5000 */ + .supply = "VDDA", + .dev_name = "1-000a", + }, + { + /* sgtl5000 */ + .supply = "VDDIO", + .dev_name = "1-000a", + }, +}; + +struct mc13892; + +static struct regulator_init_data sw1_init = { + .constraints = { + .name = "SW1", + .min_uV = mV_to_uV(600), + .max_uV = mV_to_uV(1375), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 850000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), + .consumer_supplies = sw1_consumers, +}; + +static struct regulator_init_data sw2_init = { + .constraints = { + .name = "SW2", + .min_uV = mV_to_uV(900), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 950000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + } +}; + +static struct regulator_init_data sw3_init = { + .constraints = { + .name = "SW3", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data sw4_init = { + .constraints = { + .name = "SW4", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data viohi_init = { + .constraints = { + .name = "VIOHI", + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb_init = { + .constraints = { + .name = "VUSB", + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data swbst_init = { + .constraints = { + .name = "SWBST", + } +}; + +static struct regulator_init_data vdig_init = { + .constraints = { + .name = "VDIG", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(1200), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + .always_on = 1, + }, +}; + +static struct regulator_init_data vpll_init = { + .constraints = { + .name = "VPLL", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data vusb2_init = { + .constraints = { + .name = "VUSB2", + .min_uV = mV_to_uV(2400), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + .always_on = 1, + } +}; + +static struct regulator_init_data vvideo_init = { + .constraints = { + .name = "VVIDEO", + .min_uV = mV_to_uV(2775), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .apply_uV = 1, + }, +}; + +static struct regulator_init_data vaudio_init = { + .constraints = { + .name = "VAUDIO", + .min_uV = mV_to_uV(2300), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vsd_init = { + .constraints = { + .name = "VSD", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + } +}; + +static struct regulator_init_data vcam_init = { + .constraints = { + .name = "VCAM", + .min_uV = mV_to_uV(2500), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL, + .always_on = 1, + } +}; + +static struct regulator_init_data vgen1_init = { + .constraints = { + .name = "VGEN1", + .min_uV = mV_to_uV(3000), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers), + .consumer_supplies = vgen1_consumers, +}; + +static struct regulator_init_data vgen2_init = { + .constraints = { + .name = "VGEN2", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + } +}; + +static struct regulator_init_data vgen3_init = { + .constraints = { + .name = "VGEN3", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(2900), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + } +}; + +static struct regulator_init_data gpo1_init = { + .constraints = { + .name = "GPO1", + } +}; + +static struct regulator_init_data gpo2_init = { + .constraints = { + .name = "GPO2", + } +}; + +static struct regulator_init_data gpo3_init = { + .constraints = { + .name = "GPO3", + } +}; + +static struct regulator_init_data gpo4_init = { + .constraints = { + .name = "GPO4", + } +}; + +static int mc13892_regulator_init(struct mc13892 *mc13892) +{ + unsigned int value, register_mask; + printk("Initializing regulators for mx50 arm2.\n"); + sw2_init.constraints.state_mem.uV = 1200000; + sw1_init.constraints.state_mem.uV = 1000000; + + /* enable standby controll for all regulators */ + pmic_read_reg(REG_MODE_0, &value, 0xffffff); + value |= REG_MODE_0_ALL_MASK; + pmic_write_reg(REG_MODE_0, value, 0xffffff); + + pmic_read_reg(REG_MODE_1, &value, 0xffffff); + value |= REG_MODE_1_ALL_MASK; + pmic_write_reg(REG_MODE_1, value, 0xffffff); + + /* enable switch audo mode */ + pmic_read_reg(REG_IDENTIFICATION, &value, 0xffffff); + /* only for mc13892 2.0A */ + if ((value & 0x0000FFFF) == 0x45d0) { + pmic_read_reg(REG_SW_4, &value, 0xffffff); + register_mask = (SWMODE_MASK << SW1MODE_LSB) | + (SWMODE_MASK << SW2MODE_LSB); + value &= ~register_mask; + value |= (SWMODE_AUTO << SW1MODE_LSB) | + (SWMODE_AUTO << SW2MODE_LSB); + pmic_write_reg(REG_SW_4, value, 0xffffff); + + pmic_read_reg(REG_SW_5, &value, 0xffffff); + register_mask = (SWMODE_MASK << SW3MODE_LSB) | + (SWMODE_MASK << SW4MODE_LSB); + value &= ~register_mask; + value |= (SWMODE_AUTO << SW3MODE_LSB) | + (SWMODE_AUTO << SW4MODE_LSB); + pmic_write_reg(REG_SW_5, value, 0xffffff); + } + + /* Enable coin cell charger */ + value = BITFVAL(COINCHEN, 1) | BITFVAL(VCOIN, VCOIN_3_0V); + register_mask = BITFMASK(COINCHEN) | BITFMASK(VCOIN); + pmic_write_reg(REG_POWER_CTL0, value, register_mask); + +#if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE) + value = BITFVAL(DRM, 1); + register_mask = BITFMASK(DRM); + pmic_write_reg(REG_POWER_CTL0, value, register_mask); +#endif + + mc13892_register_regulator(mc13892, MC13892_SW1, &sw1_init); + mc13892_register_regulator(mc13892, MC13892_SW2, &sw2_init); + mc13892_register_regulator(mc13892, MC13892_SW3, &sw3_init); + mc13892_register_regulator(mc13892, MC13892_SW4, &sw4_init); + mc13892_register_regulator(mc13892, MC13892_SWBST, &swbst_init); + mc13892_register_regulator(mc13892, MC13892_VIOHI, &viohi_init); + mc13892_register_regulator(mc13892, MC13892_VPLL, &vpll_init); + mc13892_register_regulator(mc13892, MC13892_VDIG, &vdig_init); + mc13892_register_regulator(mc13892, MC13892_VSD, &vsd_init); + mc13892_register_regulator(mc13892, MC13892_VUSB2, &vusb2_init); + mc13892_register_regulator(mc13892, MC13892_VVIDEO, &vvideo_init); + mc13892_register_regulator(mc13892, MC13892_VAUDIO, &vaudio_init); + mc13892_register_regulator(mc13892, MC13892_VCAM, &vcam_init); + mc13892_register_regulator(mc13892, MC13892_VGEN1, &vgen1_init); + mc13892_register_regulator(mc13892, MC13892_VGEN2, &vgen2_init); + mc13892_register_regulator(mc13892, MC13892_VGEN3, &vgen3_init); + mc13892_register_regulator(mc13892, MC13892_VUSB, &vusb_init); + mc13892_register_regulator(mc13892, MC13892_GPO1, &gpo1_init); + mc13892_register_regulator(mc13892, MC13892_GPO2, &gpo2_init); + mc13892_register_regulator(mc13892, MC13892_GPO3, &gpo3_init); + mc13892_register_regulator(mc13892, MC13892_GPO4, &gpo4_init); + + regulator_has_full_constraints(); + + return 0; +} + +static struct mc13892_platform_data mc13892_plat = { + .init = mc13892_regulator_init, +}; + +static struct spi_board_info __initdata mc13892_spi_device = { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX50_PIN_ECSPI2_MISO), + .max_speed_hz = 6000000, /* max spi SCK clock speed in HZ */ + .bus_num = 3, + .chip_select = 0, + .platform_data = &mc13892_plat, +}; + + +int __init mx50_arm2_init_mc13892(void) +{ + return spi_register_board_info(&mc13892_spi_device, 1); +} diff --git a/arch/arm/mach-mx5/mx50_pins.h b/arch/arm/mach-mx5/mx50_pins.h new file mode 100644 index 000000000000..75d654442429 --- /dev/null +++ b/arch/arm/mach-mx5/mx50_pins.h @@ -0,0 +1,340 @@ +/* + * 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. + */ +#ifndef __ASM_ARCH_MXC_MX50_PINS_H__ +#define __ASM_ARCH_MXC_MX50_PINS_H__ +#include "iomux.h" + +/*! + * @file mach-mx5/mx50_pins.h + * + * @brief MX50 I/O Pin List + * + * @ingroup GPIO_MX50 + */ + +#ifndef __ASSEMBLY__ + +#define PAD_I_START_MX50 0x2CC + +#define _MXC_BUILD_PIN_MX50(gp, gi, ga, mi, pi) \ + (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | \ + ((mi) << MUX_I) | \ + ((pi - PAD_I_START_MX50) << PAD_I) | \ + ((ga) << GPIO_I)) + +#define _MXC_BUILD_GPIO_PIN_MX50(gp, gi, ga, mi, pi) \ + _MXC_BUILD_PIN_MX50(gp, gi, ga, mi, pi) + +#define _MXC_BUILD_NON_GPIO_PIN_MX50(mi, pi) \ + _MXC_BUILD_PIN_MX50(NON_GPIO_PORT, 0, 0, mi, pi) +/*! + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX50 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ +enum iomux_pins { + MX50_PIN_KEY_COL0 = _MXC_BUILD_GPIO_PIN_MX50(3, 0, 1, 0x20, 0x2CC), + MX50_PIN_KEY_ROW0 = _MXC_BUILD_GPIO_PIN_MX50(3, 1, 1, 0x24, 0x2D0), + MX50_PIN_KEY_COL1 = _MXC_BUILD_GPIO_PIN_MX50(3, 2, 1, 0x28, 0x2D4), + MX50_PIN_KEY_ROW1 = _MXC_BUILD_GPIO_PIN_MX50(3, 3, 1, 0x2C, 0x2D8), + MX50_PIN_KEY_COL2 = _MXC_BUILD_GPIO_PIN_MX50(3, 4, 1, 0x30, 0x2DC), + MX50_PIN_KEY_ROW2 = _MXC_BUILD_GPIO_PIN_MX50(3, 5, 1, 0x34, 0x2E0), + MX50_PIN_KEY_COL3 = _MXC_BUILD_GPIO_PIN_MX50(3, 6, 1, 0x38, 0x2E4), + MX50_PIN_KEY_ROW3 = _MXC_BUILD_GPIO_PIN_MX50(3, 7, 1, 0x3C, 0x2E8), + MX50_PIN_I2C1_SCL = _MXC_BUILD_GPIO_PIN_MX50(5, 18, 1, 0x40, 0x2EC), + MX50_PIN_I2C1_SDA = _MXC_BUILD_GPIO_PIN_MX50(5, 19, 1, 0x44, 0x2F0), + MX50_PIN_I2C2_SCL = _MXC_BUILD_GPIO_PIN_MX50(5, 20, 1, 0x48, 0x2F4), + MX50_PIN_I2C2_SDA = _MXC_BUILD_GPIO_PIN_MX50(5, 21, 1, 0x4C, 0x2F8), + MX50_PIN_I2C3_SCL = _MXC_BUILD_GPIO_PIN_MX50(5, 22, 1, 0x50, 0x2FC), + MX50_PIN_I2C3_SDA = _MXC_BUILD_GPIO_PIN_MX50(5, 23, 1, 0x54, 0x300), + MX50_PIN_PWM1 = _MXC_BUILD_GPIO_PIN_MX50(5, 24, 1, 0x58, 0x304), + MX50_PIN_PWM2 = _MXC_BUILD_GPIO_PIN_MX50(5, 25, 1, 0x5C, 0x308), + MX50_PIN_OWIRE = _MXC_BUILD_GPIO_PIN_MX50(5, 26, 1, 0x60, 0x30C), + MX50_PIN_EPITO = _MXC_BUILD_GPIO_PIN_MX50(5, 27, 1, 0x64, 0x310), + MX50_PIN_WDOG = _MXC_BUILD_GPIO_PIN_MX50(5, 28, 1, 0x68, 0x314), + MX50_PIN_SSI_TXFS = _MXC_BUILD_GPIO_PIN_MX50(5, 0, 1, 0x6C, 0x318), + MX50_PIN_SSI_TXC = _MXC_BUILD_GPIO_PIN_MX50(5, 1, 1, 0x70, 0x31C), + MX50_PIN_SSI_TXD = _MXC_BUILD_GPIO_PIN_MX50(5, 2, 1, 0x74, 0x320), + MX50_PIN_SSI_RXD = _MXC_BUILD_GPIO_PIN_MX50(5, 3, 1, 0x78, 0x324), + MX50_PIN_SSI_RXFS = _MXC_BUILD_GPIO_PIN_MX50(5, 4, 1, 0x7C, 0x328), + MX50_PIN_SSI_RXC = _MXC_BUILD_GPIO_PIN_MX50(5, 5, 1, 0x80, 0x32C), + MX50_PIN_UART1_TXD = _MXC_BUILD_GPIO_PIN_MX50(5, 6, 1, 0x84, 0x330), + MX50_PIN_UART1_RXD = _MXC_BUILD_GPIO_PIN_MX50(5, 7, 1, 0x88, 0x334), + MX50_PIN_UART1_CTS = _MXC_BUILD_GPIO_PIN_MX50(5, 8, 1, 0x8C, 0x338), + MX50_PIN_UART1_RTS = _MXC_BUILD_GPIO_PIN_MX50(5, 9, 1, 0x90, 0x33C), + MX50_PIN_UART2_TXD = _MXC_BUILD_GPIO_PIN_MX50(5, 10, 1, 0x94, 0x340), + MX50_PIN_UART2_RXD = _MXC_BUILD_GPIO_PIN_MX50(5, 11, 1, 0x98, 0x344), + MX50_PIN_UART2_CTS = _MXC_BUILD_GPIO_PIN_MX50(5, 12, 1, 0x9C, 0x348), + MX50_PIN_UART2_RTS = _MXC_BUILD_GPIO_PIN_MX50(5, 13, 1, 0xA0, 0x34C), + MX50_PIN_UART3_TXD = _MXC_BUILD_GPIO_PIN_MX50(5, 14, 1, 0xA4, 0x350), + MX50_PIN_UART3_RXD = _MXC_BUILD_GPIO_PIN_MX50(5, 15, 1, 0xA8, 0x354), + MX50_PIN_UART4_TXD = _MXC_BUILD_GPIO_PIN_MX50(5, 16, 1, 0xAC, 0x358), + MX50_PIN_UART4_RXD = _MXC_BUILD_GPIO_PIN_MX50(5, 17, 1, 0xB0, 0x35C), + MX50_PIN_CSPI_SCLK = _MXC_BUILD_GPIO_PIN_MX50(3, 8, 1, 0xB4, 0x360), + MX50_PIN_CSPI_MOSI = _MXC_BUILD_GPIO_PIN_MX50(3, 9, 1, 0xB8, 0x364), + MX50_PIN_CSPI_MISO = _MXC_BUILD_GPIO_PIN_MX50(3, 10, 1, 0xBC, 0x368), + MX50_PIN_CSPI_SS0 = _MXC_BUILD_GPIO_PIN_MX50(3, 11, 1, 0xC0, 0x36C), + MX50_PIN_ECSPI1_SCLK = _MXC_BUILD_GPIO_PIN_MX50(3, 12, 1, 0xC4, 0x370), + MX50_PIN_ECSPI1_MOSI = _MXC_BUILD_GPIO_PIN_MX50(3, 13, 1, 0xC8, 0x374), + MX50_PIN_ECSPI1_MISO = _MXC_BUILD_GPIO_PIN_MX50(3, 14, 1, 0xCC, 0x378), + MX50_PIN_ECSPI1_SS0 = _MXC_BUILD_GPIO_PIN_MX50(3, 15, 1, 0xD0, 0x37C), + MX50_PIN_ECSPI2_SCLK = _MXC_BUILD_GPIO_PIN_MX50(3, 16, 1, 0xD4, 0x380), + MX50_PIN_ECSPI2_MOSI = _MXC_BUILD_GPIO_PIN_MX50(3, 17, 1, 0xD8, 0x384), + MX50_PIN_ECSPI2_MISO = _MXC_BUILD_GPIO_PIN_MX50(3, 18, 1, 0xDC, 0x388), + MX50_PIN_ECSPI2_SS0 = _MXC_BUILD_GPIO_PIN_MX50(3, 19, 1, 0xE0, 0x38C), + MX50_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN_MX50(4, 0, 1, 0xE4, 0x390), + MX50_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN_MX50(4, 1, 1, 0xE8, 0x394), + MX50_PIN_SD1_D0 = _MXC_BUILD_GPIO_PIN_MX50(4, 2, 1, 0xEC, 0x398), + MX50_PIN_SD1_D1 = _MXC_BUILD_GPIO_PIN_MX50(4, 3, 1, 0xF0, 0x39C), + MX50_PIN_SD1_D2 = _MXC_BUILD_GPIO_PIN_MX50(4, 4, 1, 0xF4, 0x3A0), + MX50_PIN_SD1_D3 = _MXC_BUILD_GPIO_PIN_MX50(4, 5, 1, 0xF8, 0x3A4), + MX50_PIN_SD2_CLK = _MXC_BUILD_GPIO_PIN_MX50(4, 6, 1, 0xFC, 0x3A8), + MX50_PIN_SD2_CMD = _MXC_BUILD_GPIO_PIN_MX50(4, 7, 1, 0x100, 0x3AC), + MX50_PIN_SD2_D0 = _MXC_BUILD_GPIO_PIN_MX50(4, 8, 1, 0x104, 0x3B0), + MX50_PIN_SD2_D1 = _MXC_BUILD_GPIO_PIN_MX50(4, 9, 1, 0x108, 0x3B4), + MX50_PIN_SD2_D2 = _MXC_BUILD_GPIO_PIN_MX50(4, 10, 1, 0x10C, 0x3B8), + MX50_PIN_SD2_D3 = _MXC_BUILD_GPIO_PIN_MX50(4, 11, 1, 0x110, 0x3BC), + MX50_PIN_SD2_D4 = _MXC_BUILD_GPIO_PIN_MX50(4, 12, 1, 0x114, 0x3C0), + MX50_PIN_SD2_D5 = _MXC_BUILD_GPIO_PIN_MX50(4, 13, 1, 0x118, 0x3C4), + MX50_PIN_SD2_D6 = _MXC_BUILD_GPIO_PIN_MX50(4, 14, 1, 0x11C, 0x3C8), + MX50_PIN_SD2_D7 = _MXC_BUILD_GPIO_PIN_MX50(4, 15, 1, 0x120, 0x3CC), + MX50_PIN_SD2_WP = _MXC_BUILD_GPIO_PIN_MX50(4, 16, 1, 0x124, 0x3D0), + MX50_PIN_SD2_CD = _MXC_BUILD_GPIO_PIN_MX50(4, 17, 1, 0x128, 0x3D4), + + MX50_PIN_PMIC_ON_REQ = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3D8), + MX50_PIN_PMIC_STBY_REQ = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3DC), + MX50_PIN_PMIC_PORT_B = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3E0), + MX50_PIN_PMIC_BOOT_MODE1 = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3E4), + MX50_PIN_PMIC_RESET_IN_B = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3E8), + MX50_PIN_PMIC_BOOT_MODE0 = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3EC), + MX50_PIN_PMIC_TEST_MODE = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3F0), + MX50_PIN_PMIC_JTAG_TMS = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3F4), + MX50_PIN_PMIC_JTAG_MOD = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3F8), + MX50_PIN_PMIC_JTAG_TRSTB = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x3FC), + MX50_PIN_PMIC_JTAG_TDI = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x400), + MX50_PIN_PMIC_JTAG_TCK = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x404), + MX50_PIN_PMIC_JTAG_TDO = _MXC_BUILD_NON_GPIO_PIN_MX50(NON_MUX_I, 0x408), + + MX50_PIN_DISP_D0 = _MXC_BUILD_GPIO_PIN_MX50(1, 0, 1, 0x12C, 0x40C), + MX50_PIN_DISP_D1 = _MXC_BUILD_GPIO_PIN_MX50(1, 1, 1, 0x130, 0x410), + MX50_PIN_DISP_D2 = _MXC_BUILD_GPIO_PIN_MX50(1, 2, 1, 0x134, 0x414), + MX50_PIN_DISP_D3 = _MXC_BUILD_GPIO_PIN_MX50(1, 3, 1, 0x138, 0x418), + MX50_PIN_DISP_D4 = _MXC_BUILD_GPIO_PIN_MX50(1, 4, 1, 0x13C, 0x41C), + MX50_PIN_DISP_D5 = _MXC_BUILD_GPIO_PIN_MX50(1, 5, 1, 0x140, 0x420), + MX50_PIN_DISP_D6 = _MXC_BUILD_GPIO_PIN_MX50(1, 6, 1, 0x144, 0x424), + MX50_PIN_DISP_D7 = _MXC_BUILD_GPIO_PIN_MX50(1, 7, 1, 0x148, 0x428), + MX50_PIN_DISP_WR = _MXC_BUILD_GPIO_PIN_MX50(1, 16, 1, 0x14C, 0x42C), + MX50_PIN_DISP_RD = _MXC_BUILD_GPIO_PIN_MX50(1, 19, 1, 0x150, 0x430), + MX50_PIN_DISP_RS = _MXC_BUILD_GPIO_PIN_MX50(1, 17, 1, 0x154, 0x434), + MX50_PIN_DISP_CS = _MXC_BUILD_GPIO_PIN_MX50(1, 21, 1, 0x158, 0x438), + MX50_PIN_DISP_BUSY = _MXC_BUILD_GPIO_PIN_MX50(1, 18, 1, 0x15C, 0x43C), + MX50_PIN_DISP_RESET = _MXC_BUILD_GPIO_PIN_MX50(1, 20, 1, 0x160, 0x440), + MX50_PIN_SD3_CMD = _MXC_BUILD_GPIO_PIN_MX50(4, 18, 1, 0x164, 0x444), + MX50_PIN_SD3_CLK = _MXC_BUILD_GPIO_PIN_MX50(4, 19, 1, 0x168, 0x448), + MX50_PIN_SD3_D0 = _MXC_BUILD_GPIO_PIN_MX50(4, 20, 1, 0x16C, 0x44C), + MX50_PIN_SD3_D1 = _MXC_BUILD_GPIO_PIN_MX50(4, 21, 1, 0x170, 0x450), + MX50_PIN_SD3_D2 = _MXC_BUILD_GPIO_PIN_MX50(4, 22, 1, 0x174, 0x454), + MX50_PIN_SD3_D3 = _MXC_BUILD_GPIO_PIN_MX50(4, 23, 1, 0x178, 0x458), + MX50_PIN_SD3_D4 = _MXC_BUILD_GPIO_PIN_MX50(4, 24, 1, 0x17C, 0x45C), + MX50_PIN_SD3_D5 = _MXC_BUILD_GPIO_PIN_MX50(4, 25, 1, 0x180, 0x460), + MX50_PIN_SD3_D6 = _MXC_BUILD_GPIO_PIN_MX50(4, 26, 1, 0x184, 0x464), + MX50_PIN_SD3_D7 = _MXC_BUILD_GPIO_PIN_MX50(4, 27, 1, 0x188, 0x468), + MX50_PIN_SD3_WP = _MXC_BUILD_GPIO_PIN_MX50(4, 28, 1, 0x18C, 0x46C), + MX50_PIN_DISP_D8 = _MXC_BUILD_GPIO_PIN_MX50(1, 8, 1, 0x190, 0x470), + MX50_PIN_DISP_D9 = _MXC_BUILD_GPIO_PIN_MX50(1, 9, 1, 0x194, 0x474), + MX50_PIN_DISP_D10 = _MXC_BUILD_GPIO_PIN_MX50(1, 10, 1, 0x198, 0x478), + MX50_PIN_DISP_D11 = _MXC_BUILD_GPIO_PIN_MX50(1, 11, 1, 0x19C, 0x47C), + MX50_PIN_DISP_D12 = _MXC_BUILD_GPIO_PIN_MX50(1, 12, 1, 0x1A0, 0x480), + MX50_PIN_DISP_D13 = _MXC_BUILD_GPIO_PIN_MX50(1, 13, 1, 0x1A4, 0x484), + MX50_PIN_DISP_D14 = _MXC_BUILD_GPIO_PIN_MX50(1, 14, 1, 0x1A8, 0x488), + MX50_PIN_DISP_D15 = _MXC_BUILD_GPIO_PIN_MX50(1, 15, 1, 0x1AC, 0x48C), + + MX50_PIN_EPDC_D0 = _MXC_BUILD_GPIO_PIN_MX50(2, 0, 1, 0x1B0, 0x54C), + MX50_PIN_EPDC_D1 = _MXC_BUILD_GPIO_PIN_MX50(2, 1, 1, 0x1B4, 0x550), + MX50_PIN_EPDC_D2 = _MXC_BUILD_GPIO_PIN_MX50(2, 2, 1, 0x1B8, 0x554), + MX50_PIN_EPDC_D3 = _MXC_BUILD_GPIO_PIN_MX50(2, 3, 1, 0x1BC, 0x558), + MX50_PIN_EPDC_D4 = _MXC_BUILD_GPIO_PIN_MX50(2, 4, 1, 0x1C0, 0x55C), + MX50_PIN_EPDC_D5 = _MXC_BUILD_GPIO_PIN_MX50(2, 5, 1, 0x1C4, 0x560), + MX50_PIN_EPDC_D6 = _MXC_BUILD_GPIO_PIN_MX50(2, 6, 1, 0x1C8, 0x564), + MX50_PIN_EPDC_D7 = _MXC_BUILD_GPIO_PIN_MX50(2, 7, 1, 0x1CC, 0x568), + MX50_PIN_EPDC_D8 = _MXC_BUILD_GPIO_PIN_MX50(2, 8, 1, 0x1D0, 0x56C), + MX50_PIN_EPDC_D9 = _MXC_BUILD_GPIO_PIN_MX50(2, 9, 1, 0x1D4, 0x570), + MX50_PIN_EPDC_D10 = _MXC_BUILD_GPIO_PIN_MX50(2, 10, 1, 0x1D8, 0x574), + MX50_PIN_EPDC_D11 = _MXC_BUILD_GPIO_PIN_MX50(2, 11, 1, 0x1DC, 0x578), + MX50_PIN_EPDC_D12 = _MXC_BUILD_GPIO_PIN_MX50(2, 12, 1, 0x1E0, 0x57C), + MX50_PIN_EPDC_D13 = _MXC_BUILD_GPIO_PIN_MX50(2, 13, 1, 0x1E4, 0x580), + MX50_PIN_EPDC_D14 = _MXC_BUILD_GPIO_PIN_MX50(2, 14, 1, 0x1E8, 0x584), + MX50_PIN_EPDC_D15 = _MXC_BUILD_GPIO_PIN_MX50(2, 15, 1, 0x1EC, 0x588), + MX50_PIN_EPDC_GDCLK = _MXC_BUILD_GPIO_PIN_MX50(2, 16, 1, 0x1F0, 0x58C), + MX50_PIN_EPDC_GDSP = _MXC_BUILD_GPIO_PIN_MX50(2, 17, 1, 0x1F4, 0x590), + MX50_PIN_EPDC_GDOE = _MXC_BUILD_GPIO_PIN_MX50(2, 18, 1, 0x1F8, 0x594), + MX50_PIN_EPDC_GDRL = _MXC_BUILD_GPIO_PIN_MX50(2, 19, 1, 0x1FC, 0x598), + MX50_PIN_EPDC_SDCLK = _MXC_BUILD_GPIO_PIN_MX50(2, 20, 1, 0x200, 0x59C), + MX50_PIN_EPDC_SDOEZ = _MXC_BUILD_GPIO_PIN_MX50(2, 21, 1, 0x204, 0x5A0), + MX50_PIN_EPDC_SDOED = _MXC_BUILD_GPIO_PIN_MX50(2, 22, 1, 0x208, 0x5A4), + MX50_PIN_EPDC_SDOE = _MXC_BUILD_GPIO_PIN_MX50(2, 23, 1, 0x20C, 0x5A8), + MX50_PIN_EPDC_SDLE = _MXC_BUILD_GPIO_PIN_MX50(2, 24, 1, 0x210, 0x5AC), + MX50_PIN_EPDC_SDCLKN = _MXC_BUILD_GPIO_PIN_MX50(2, 25, 1, 0x214, 0x5B0), + MX50_PIN_EPDC_SDSHR = _MXC_BUILD_GPIO_PIN_MX50(2, 26, 1, 0x218, 0x5B4), + MX50_PIN_EPDC_PWRCOM = _MXC_BUILD_GPIO_PIN_MX50(2, 27, 1, 0x21C, 0x5B8), + MX50_PIN_EPDC_PWRSTAT = _MXC_BUILD_GPIO_PIN_MX50(2, 28, 1, 0x220, 0x5BC), + MX50_PIN_EPDC_PWRCTRL0 = _MXC_BUILD_GPIO_PIN_MX50(2, 29, 1, 0x224, 0x5C0), + MX50_PIN_EPDC_PWRCTRL1 = _MXC_BUILD_GPIO_PIN_MX50(2, 30, 1, 0x228, 0x5C4), + MX50_PIN_EPDC_PWRCTRL2 = _MXC_BUILD_GPIO_PIN_MX50(2, 31, 1, 0x22C, 0x5C8), + MX50_PIN_EPDC_PWRCTRL3 = _MXC_BUILD_GPIO_PIN_MX50(3, 20, 1, 0x230, 0x5CC), + MX50_PIN_EPDC_VCOM0 = _MXC_BUILD_GPIO_PIN_MX50(3, 21, 1, 0x234, 0x5D0), + MX50_PIN_EPDC_VCOM1 = _MXC_BUILD_GPIO_PIN_MX50(3, 22, 1, 0x238, 0x5D4), + MX50_PIN_EPDC_BDR0 = _MXC_BUILD_GPIO_PIN_MX50(3, 23, 1, 0x23C, 0x5D8), + MX50_PIN_EPDC_BDR1 = _MXC_BUILD_GPIO_PIN_MX50(3, 24, 1, 0x240, 0x5DC), + MX50_PIN_EPDC_SDCE0 = _MXC_BUILD_GPIO_PIN_MX50(3, 25, 1, 0x244, 0x5E0), + MX50_PIN_EPDC_SDCE1 = _MXC_BUILD_GPIO_PIN_MX50(3, 26, 1, 0x248, 0x5E4), + MX50_PIN_EPDC_SDCE2 = _MXC_BUILD_GPIO_PIN_MX50(3, 27, 1, 0x24C, 0x5E8), + MX50_PIN_EPDC_SDCE3 = _MXC_BUILD_GPIO_PIN_MX50(3, 28, 1, 0x250, 0x5EC), + MX50_PIN_EPDC_SDCE4 = _MXC_BUILD_GPIO_PIN_MX50(3, 29, 1, 0x254, 0x5F0), + MX50_PIN_EPDC_SDCE5 = _MXC_BUILD_GPIO_PIN_MX50(3, 30, 1, 0x258, 0x5F4), + MX50_PIN_EIM_DA0 = _MXC_BUILD_GPIO_PIN_MX50(0, 0, 1, 0x25C, 0x5F8), + MX50_PIN_EIM_DA1 = _MXC_BUILD_GPIO_PIN_MX50(0, 1, 1, 0x260, 0x5FC), + MX50_PIN_EIM_DA2 = _MXC_BUILD_GPIO_PIN_MX50(0, 2, 1, 0x264, 0x600), + MX50_PIN_EIM_DA3 = _MXC_BUILD_GPIO_PIN_MX50(0, 3, 1, 0x268, 0x604), + MX50_PIN_EIM_DA4 = _MXC_BUILD_GPIO_PIN_MX50(0, 4, 1, 0x26C, 0x608), + MX50_PIN_EIM_DA5 = _MXC_BUILD_GPIO_PIN_MX50(0, 5, 1, 0x270, 0x60C), + MX50_PIN_EIM_DA6 = _MXC_BUILD_GPIO_PIN_MX50(0, 6, 1, 0x274, 0x610), + MX50_PIN_EIM_DA7 = _MXC_BUILD_GPIO_PIN_MX50(0, 7, 1, 0x278, 0x614), + MX50_PIN_EIM_DA8 = _MXC_BUILD_GPIO_PIN_MX50(0, 8, 1, 0x27C, 0x618), + MX50_PIN_EIM_DA9 = _MXC_BUILD_GPIO_PIN_MX50(0, 9, 1, 0x280, 0x61C), + MX50_PIN_EIM_DA10 = _MXC_BUILD_GPIO_PIN_MX50(0, 10, 1, 0x284, 0x620), + MX50_PIN_EIM_DA11 = _MXC_BUILD_GPIO_PIN_MX50(0, 11, 1, 0x288, 0x624), + MX50_PIN_EIM_DA12 = _MXC_BUILD_GPIO_PIN_MX50(0, 12, 1, 0x28C, 0x628), + MX50_PIN_EIM_DA13 = _MXC_BUILD_GPIO_PIN_MX50(0, 13, 1, 0x290, 0x62C), + MX50_PIN_EIM_DA14 = _MXC_BUILD_GPIO_PIN_MX50(0, 14, 1, 0x294, 0x630), + MX50_PIN_EIM_DA15 = _MXC_BUILD_GPIO_PIN_MX50(0, 15, 1, 0x298, 0x634), + MX50_PIN_EIM_CS2 = _MXC_BUILD_GPIO_PIN_MX50(0, 16, 1, 0x29C, 0x638), + MX50_PIN_EIM_CS1 = _MXC_BUILD_GPIO_PIN_MX50(0, 17, 1, 0x2A0, 0x63C), + MX50_PIN_EIM_CS0 = _MXC_BUILD_GPIO_PIN_MX50(0, 18, 1, 0x2A4, 0x640), + MX50_PIN_EIM_EB0 = _MXC_BUILD_GPIO_PIN_MX50(0, 19, 1, 0x2A8, 0x644), + MX50_PIN_EIM_EB1 = _MXC_BUILD_GPIO_PIN_MX50(0, 20, 1, 0x2AC, 0x648), + MX50_PIN_EIM_WAIT = _MXC_BUILD_GPIO_PIN_MX50(0, 21, 1, 0x2B0, 0x64C), + MX50_PIN_EIM_BCLK = _MXC_BUILD_GPIO_PIN_MX50(0, 22, 1, 0x2B4, 0x650), + MX50_PIN_EIM_RDY = _MXC_BUILD_GPIO_PIN_MX50(0, 23, 1, 0x2B8, 0x654), + MX50_PIN_EIM_OE = _MXC_BUILD_GPIO_PIN_MX50(0, 24, 1, 0x2BC, 0x658), + MX50_PIN_EIM_RW = _MXC_BUILD_GPIO_PIN_MX50(0, 25, 1, 0x2C0, 0x65C), + MX50_PIN_EIM_LBA = _MXC_BUILD_GPIO_PIN_MX50(0, 26, 1, 0x2C4, 0x660), + MX50_PIN_EIM_CRE = _MXC_BUILD_GPIO_PIN_MX50(0, 27, 1, 0x2C8, 0x664), + +}; + +/*! + * various IOMUX input select register index + */ +enum iomux_input_select_mx50 { + MUX_IN_AUDMUX_P4_INPUT_DA_AMX_SELECT_I = 0, + MUX_IN_AUDMUX_P4_INPUT_DB_AMX_SELECT_I, + MUX_IN_AUDMUX_P4_INPUT_RXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P4_INPUT_RXFS_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT, + MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT, + MUX_IN_CCM_PLL2_BYPASS_CLK_SELECT_INPUT, + MUX_IN_CCM_PLL3_BYPASS_CLK_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_DATAREADY_B_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS1_B_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS2_B_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS3_B_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_BUSY_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_0_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_1_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_2_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_3_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_4_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_5_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_6_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_7_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_8_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_9_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_10_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_11_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_12_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_13_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_14_SELECT_INPUT, + MUX_IN_ELCDIF_LCDIF_RXDATA_15_SELECT_INPUT, + MUX_IN_ELCDIF_VSYNC_I_SELECT_INPUT, + MUX_IN_ESDHC2_IPP_CARD_DET_SELECT_INPUT, + MUX_IN_ESDHC2_IPP_WP_ON_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_CARD_CLK_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_CMD_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT0_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT1_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT2_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT3_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT4_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT5_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT6_IN_SELECT_INPUT, + MUX_IN_ESDHC4_IPP_DAT7_IN_SELECT_INPUT, + MUX_IN_FEC_FEC_COL_SELECT_INPUT, + MUX_IN_FEC_FEC_MDI_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_0_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_1_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_CLK_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_DV_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_ER_SELECT_INPUT, + MUX_IN_FEC_FEC_TX_CLK_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_COL_4_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_COL_5_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_COL_7_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_4_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_5_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_6_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_7_SELECT_INPUT, + MUX_IN_RAWNAND_U_GPMI_INPUT_GPMI_DQS_IN_SELECT_INPUT, + MUX_IN_RAWNAND_U_GPMI_INPUT_GPMI_RDY0_IN_SELECT_INPUT, + MUX_IN_SDMA_EVENTS_14_SELECT_INPUT, + MUX_IN_SDMA_EVENTS_15_SELECT_INPUT, + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART4_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART4_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART5_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART5_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_USBOH1_IPP_IND_OTG_OC_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_0_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_1_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_2_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_3_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_4_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_5_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_6_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_7_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_8_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_9_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_10_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_11_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_12_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_13_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_14_SELECT_INPUT, + MUX_IN_WEIMV2_IPP_IND_READ_DATA_15_SELECT_INPUT, + + MUX_INPUT_NUM_MUX, +}; + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_MXC_MX50_PINS_H__ */ diff --git a/arch/arm/mach-mx5/mx51_3stack.c b/arch/arm/mach-mx5/mx51_3stack.c index 7c3d80938777..4fade5a37ac2 100644 --- a/arch/arm/mach-mx5/mx51_3stack.c +++ b/arch/arm/mach-mx5/mx51_3stack.c @@ -47,7 +47,6 @@ #include <mach/mxc_dvfs.h> #include "devices.h" -#include "board-mx51_3stack.h" #include "iomux.h" #include "mx51_pins.h" #include "crm_regs.h" @@ -60,6 +59,44 @@ * * @ingroup MSL_MX51 */ +#define DEBUG_BOARD_BASE_ADDRESS(n) (n) +/* LAN9217 ethernet base address */ +#define LAN9217_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n)) + +#define BOARD_IO_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x20000) +/* LED switchs */ +#define LED_SWITCH_REG 0x00 +/* buttons */ +#define SWITCH_BUTTONS_REG 0x08 +/* status, interrupt */ +#define INTR_STATUS_REG 0x10 +#define INTR_MASK_REG 0x38 +#define INTR_RESET_REG 0x20 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER1_REG 0x40 +#define MAGIC_NUMBER2_REG 0x48 +/* CPLD code version */ +#define CPLD_CODE_VER_REG 0x50 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER3_REG 0x58 +/* module reset register*/ +#define MODULE_RESET_REG 0x60 +/* CPU ID and Personality ID */ +#define MCU_BOARD_ID_REG 0x68 + +/* interrupts like external uart , external ethernet etc*/ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX51_PIN_GPIO1_6) + +#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0) +#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1) +#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2) +#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3) +#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4) + +/*! This is System IRQ used by LAN9217 */ +#define LAN9217_IRQ EXPIO_INT_ENET + +extern int __init mx51_3stack_init_mc13892(void); extern void __init mx51_3stack_io_init(void); extern struct cpu_wp *(*get_cpu_wp)(int *wp); extern void (*set_num_cpu_wp)(int num); @@ -184,10 +221,6 @@ static struct mxc_dvfs_platform_data dvfs_core_data = { .ccm_cdcr_reg_addr = MXC_CCM_CDCR, .ccm_cacrr_reg_addr = MXC_CCM_CACRR, .ccm_cdhipr_reg_addr = MXC_CCM_CDHIPR, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -685,30 +718,6 @@ static struct fsl_ata_platform_data ata_data = { .io_reg = NULL, }; -static int __init mxc_init_srpgconfig(void) -{ - struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk"); - clk_enable(gpcclk); - - /* Setup the number of clock cycles to wait for SRPG - * power up and power down requests. - */ - __raw_writel(0x010F0201, MXC_SRPG_ARM_PUPSCR); - __raw_writel(0x010F0201, MXC_SRPG_NEON_PUPSCR); - __raw_writel(0x00000008, MXC_SRPG_EMPGC0_PUPSCR); - __raw_writel(0x00000008, MXC_SRPG_EMPGC1_PUPSCR); - - __raw_writel(0x01010101, MXC_SRPG_ARM_PDNSCR); - __raw_writel(0x01010101, MXC_SRPG_NEON_PDNSCR); - __raw_writel(0x00000018, MXC_SRPG_EMPGC0_PDNSCR); - __raw_writel(0x00000018, MXC_SRPG_EMPGC1_PDNSCR); - - clk_disable(gpcclk); - clk_put(gpcclk); - - return 0; -} - static struct platform_device mxc_wm8903_device = { .name = "imx-3stack-wm8903", .id = 0, @@ -909,8 +918,8 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_pwm1_device, NULL); mxc_register_device(&mxc_pwm_backlight_device, &mxc_pwm_backlight_data); mxc_register_device(&mxc_keypad_device, &keypad_plat_data); - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); mxc_register_device(&mxcsdhc1_device, &mmc1_data); mxc_register_device(&mxcsdhc2_device, &mmc2_data); mxc_register_device(&mxc_sim_device, &sim_data); @@ -936,7 +945,6 @@ static void __init mxc_board_init(void) #else mxc_register_device(&mxc_nandv2_mtd_device, &mxc_nand_data); #endif - mxc_init_srpgconfig(); mx51_3stack_init_mc13892(); i2c_register_board_info(1, mxc_i2c1_board_info, diff --git a/arch/arm/mach-mx5/mx51_babbage.c b/arch/arm/mach-mx5/mx51_babbage.c index 4a962ab6f647..6658a99e1d2e 100644 --- a/arch/arm/mach-mx5/mx51_babbage.c +++ b/arch/arm/mach-mx5/mx51_babbage.c @@ -25,7 +25,6 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> #include <linux/mtd/partitions.h> -#include <linux/spi/flash.h> #include <linux/regulator/consumer.h> #include <linux/pmic_external.h> #include <linux/pmic_status.h> @@ -39,13 +38,13 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/keypad.h> +#include <asm/mach/flash.h> #include <mach/gpio.h> #include <mach/mmc.h> #include <mach/mxc_dvfs.h> #include <mach/mxc_edid.h> #include "devices.h" -#include "board-mx51_babbage.h" #include "iomux.h" #include "mx51_pins.h" #include "crm_regs.h" @@ -58,6 +57,7 @@ * * @ingroup MSL_MX51 */ +extern int __init mx51_babbage_init_mc13892(void); extern void __init mx51_babbage_io_init(void); extern struct cpu_wp *(*get_cpu_wp)(int *wp); extern void (*set_num_cpu_wp)(int num); @@ -96,6 +96,24 @@ static struct cpu_wp cpu_wp_auto[] = { static struct fb_videomode video_modes[] = { { + /* NTSC TV output */ + "TV-NTSC", 60, 720, 480, 74074, + 122, 15, + 18, 26, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED, + 0,}, + { + /* PAL TV output */ + "TV-PAL", 50, 720, 576, 74074, + 132, 11, + 22, 26, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST, + 0,}, + { /* 720p60 TV output */ "720P60", 60, 1280, 720, 13468, 260, 109, @@ -114,6 +132,12 @@ static struct fb_videomode video_modes[] = { 0, FB_VMODE_NONINTERLACED, 0,}, + { + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */ + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, }; struct cpu_wp *mx51_babbage_get_cpu_wp(int *wp) @@ -202,10 +226,6 @@ static struct mxc_dvfs_platform_data dvfs_core_data = { .ccm_cdcr_reg_addr = MXC_CCM_CDCR, .ccm_cacrr_reg_addr = MXC_CCM_CACRR, .ccm_cdhipr_reg_addr = MXC_CCM_CDHIPR, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -258,30 +278,75 @@ static struct mxc_fb_platform_data fb_data[] = { { .interface_pix_fmt = IPU_PIX_FMT_RGB24, .mode_str = "1024x768M-16@60", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), }, { .interface_pix_fmt = IPU_PIX_FMT_RGB565, - .mode_str = "1024x768M-16@60", + .mode_str = "CLAA-WVGA", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), }, }; -static int __initdata enable_vga = { 0 }; -static int __initdata enable_wvga = { 0 }; -static int __initdata enable_tv = { 0 }; -static int __initdata enable_mitsubishi_xga = { 0 }; - -static void wvga_reset(void) +extern int primary_di; +static int __init mxc_init_fb(void) { + if (!machine_is_mx51_babbage()) + return 0; + + /* DI0-LVDS */ + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D0_CS), 0); + msleep(1); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D0_CS), 1); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI2_D12), 1); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI2_D13), 1); + + /* DVI Detect */ + gpio_request(IOMUX_TO_GPIO(MX51_PIN_NANDF_D12), "nandf_d12"); + gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_NANDF_D12)); + /* DVI Reset - Assert for i2c disabled mode */ + gpio_request(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), "dispb2_ser_din"); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); + /* DVI Power-down */ + gpio_request(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), "dispb2_ser_di0"); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), 1); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), 0); + + /* WVGA Reset */ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D1_CS), 1); -} -static struct mxc_lcd_platform_data lcd_wvga_data = { - .reset = wvga_reset, -}; + if (primary_di) { + printk(KERN_INFO "DI1 is primary\n"); -static struct platform_device lcd_wvga_device = { - .name = "lcd_claa", -}; + /* DI1 -> DP-BG channel: */ + mxc_fb_devices[1].num_resources = ARRAY_SIZE(mxcfb_resources); + mxc_fb_devices[1].resource = mxcfb_resources; + mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); + + /* DI0 -> DC channel: */ + mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); + } else { + printk(KERN_INFO "DI0 is primary\n"); + + /* DI0 -> DP-BG channel: */ + mxc_fb_devices[0].num_resources = ARRAY_SIZE(mxcfb_resources); + mxc_fb_devices[0].resource = mxcfb_resources; + mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); + + /* DI1 -> DC channel: */ + mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); + } + + /* + * DI0/1 DP-FG channel: + */ + mxc_register_device(&mxc_fb_devices[2], NULL); + + return 0; +} +device_initcall(mxc_init_fb); static int handle_edid(int *pixclk) { @@ -370,160 +435,6 @@ static int handle_edid(int *pixclk) return 0; } -static int __init mxc_init_fb(void) -{ - int pixclk = 0; - - if (!machine_is_mx51_babbage()) - return 0; - - if (cpu_is_mx51_rev(CHIP_REV_1_1) == 1) { - enable_vga = 1; - fb_data[0].mode_str = NULL; - fb_data[1].mode_str = NULL; - } - - /* DI1: Dumb LCD */ - if (enable_wvga) { - fb_data[1].interface_pix_fmt = IPU_PIX_FMT_RGB565; - fb_data[1].mode_str = "800x480M-16@55"; - } - - /* DI0: lVDS */ - if (enable_mitsubishi_xga) { - fb_data[0].interface_pix_fmt = IPU_PIX_FMT_LVDS666; - fb_data[0].mode = &(video_modes[1]); - - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D0_CS), 0); - msleep(1); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D0_CS), 1); - - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI2_D12), 1); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI2_D13), 1); - } - - /* DVI Detect */ - gpio_request(IOMUX_TO_GPIO(MX51_PIN_NANDF_D12), "nandf_d12"); - gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_NANDF_D12)); - /* DVI Reset - Assert for i2c disabled mode */ - gpio_request(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), "dispb2_ser_din"); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); - /* DVI Power-down */ - gpio_request(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), "dispb2_ser_di0"); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), 1); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIO), 0); - - mxc_register_device(&lcd_wvga_device, &lcd_wvga_data); - - if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) - handle_edid(&pixclk); - - if (enable_vga) { - printk(KERN_INFO "VGA monitor is primary\n"); - } else if (enable_wvga) { - printk(KERN_INFO "WVGA LCD panel is primary\n"); - } else if (enable_tv == 2) - printk(KERN_INFO "HDTV is primary\n"); - else - printk(KERN_INFO "DVI monitor is primary\n"); - - if (enable_tv) { - printk(KERN_INFO "HDTV is specified as %d\n", enable_tv); - fb_data[1].interface_pix_fmt = IPU_PIX_FMT_YUV444; - fb_data[1].mode = &(video_modes[0]); - } - - /* Once a customer knows the platform configuration, - this should be simplified to what is desired. - */ - if (enable_vga || enable_wvga || enable_tv == 2) { - /* - * DI1 -> DP-BG channel: - * - * dev di-out-fmt default-videmode - * - * 1. VGA RGB 1024x768M-16@60 - * 2. WVGA RGB 800x480M-16@55 - * 3. TVE YUV video_modes[0] - */ - mxc_fb_devices[1].num_resources = ARRAY_SIZE(mxcfb_resources); - mxc_fb_devices[1].resource = mxcfb_resources; - mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); - if (fb_data[0].mode_str || fb_data[0].mode) - /* - * DI0 -> DC channel: - * - * dev di-out-fmt default-videmode - * - * 1. LVDS RGB video_modes[1] - * 2. DVI RGB 1024x768M-16@60 - */ - mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); - } else { - /* - * DI0 -> DP-BG channel: - * - * dev di-out-fmt default-videmode - * - * 1. LVDS RGB video_modes[1] - * 2. DVI RGB 1024x768M-16@60 - */ - mxc_fb_devices[0].num_resources = ARRAY_SIZE(mxcfb_resources); - mxc_fb_devices[0].resource = mxcfb_resources; - mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); - if (fb_data[1].mode_str || fb_data[1].mode) - /* - * DI1 -> DC channel: - * - * dev di-out-fmt default-videmode - * - * 1. VGA RGB 1024x768M-16@60 - * 2. WVGA RGB 800x480M-16@55 - * 3. TVE YUV video_modes[0] - */ - mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); - } - - /* - * DI0/1 DP-FG channel: - */ - mxc_register_device(&mxc_fb_devices[2], NULL); - - return 0; -} -device_initcall(mxc_init_fb); - -static int __init vga_setup(char *__unused) -{ - enable_vga = 1; - return 1; -} -__setup("vga", vga_setup); - -static int __init wvga_setup(char *__unused) -{ - enable_wvga = 1; - return 1; -} -__setup("wvga", wvga_setup); - -static int __init mitsubishi_xga_setup(char *__unused) -{ - enable_mitsubishi_xga = 1; - return 1; -} -__setup("mitsubishi_xga", mitsubishi_xga_setup); - -static int __init tv_setup(char *s) -{ - enable_tv = 1; - if (strcmp(s, "2") == 0 || strcmp(s, "=2") == 0) - enable_tv = 2; - return 1; -} -__setup("hdtv", tv_setup); - static void dvi_reset(void) { gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); @@ -732,11 +643,12 @@ static unsigned int sdhc_get_card_det_status(struct device *dev) } static struct mxc_mmc_platform_data mmc1_data = { - .ocr_mask = MMC_VDD_31_32, + .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | + MMC_VDD_31_32, .caps = MMC_CAP_4_BIT_DATA, - .min_clk = 400000, + .min_clk = 150000, .max_clk = 52000000, - .card_inserted_state = 1, + .card_inserted_state = 0, .status = sdhc_get_card_det_status, .wp_status = sdhc_write_protect, .clock_mmc = "esdhc_clk", @@ -952,8 +864,6 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_pwm1_device, NULL); mxc_register_device(&mxc_pwm_backlight_device, &mxc_pwm_backlight_data); mxc_register_device(&mxc_keypad_device, &keypad_plat_data); - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), mxc_register_device(&mxcsdhc1_device, &mmc1_data); mxc_register_device(&mxcsdhc2_device, &mmc2_data); mxc_register_device(&mxc_ssi1_device, NULL); diff --git a/arch/arm/mach-mx5/mx51_babbage_gpio.c b/arch/arm/mach-mx5/mx51_babbage_gpio.c index 4b3e2ee73faf..5d484b78832b 100644 --- a/arch/arm/mach-mx5/mx51_babbage_gpio.c +++ b/arch/arm/mach-mx5/mx51_babbage_gpio.c @@ -270,59 +270,83 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { }, { MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD1_DATA0, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD1_DATA1, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD1_DATA2, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD1_DATA3, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_GPIO1_0, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), }, { - MX51_PIN_GPIO1_1, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + MX51_PIN_GPIO1_1, IOMUX_CONFIG_GPIO, (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), }, { MX51_PIN_SD2_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_SD2_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { - MX51_PIN_SD2_DATA0, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + MX51_PIN_SD2_DATA0, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { - MX51_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + MX51_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { - MX51_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + MX51_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { - MX51_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + MX51_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX51_PIN_GPIO1_4, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, @@ -461,7 +485,7 @@ static int __initdata enable_w1 = { 0 }; static int __init w1_setup(char *__unused) { enable_w1 = 1; - return 1; + return cpu_is_mx51(); } __setup("w1", w1_setup); diff --git a/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c index 4aa15f3c2515..c97d2191b94b 100644 --- a/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c +++ b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c @@ -407,7 +407,7 @@ static struct mc13892_platform_data mc13892_plat = { static struct spi_board_info __initdata mc13892_spi_device = { .modalias = "pmic_spi", .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_8), - .max_speed_hz = 1000000, /* max spi SCK clock speed in HZ */ + .max_speed_hz = 6000000, /* max spi SCK clock speed in HZ */ .bus_num = 1, .chip_select = 0, .platform_data = &mc13892_plat, diff --git a/arch/arm/mach-mx5/mx51_ccwmx51js.c b/arch/arm/mach-mx5/mx51_ccwmx51js.c index 63e0377e751b..0ac060056f35 100644 --- a/arch/arm/mach-mx5/mx51_ccwmx51js.c +++ b/arch/arm/mach-mx5/mx51_ccwmx51js.c @@ -41,8 +41,6 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <mach/memory.h> -#include <linux/input.h> -#include <linux/gpio_keys.h> #include <mach/gpio.h> #include <mach/mmc.h> #include <mach/mxc_dvfs.h> @@ -57,9 +55,10 @@ extern struct cpu_wp *(*get_cpu_wp)(int *wp); extern void (*set_num_cpu_wp)(int num); static int num_cpu_wp = 3; +u8 ccwmx51_swap_bi = 0; /* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */ -static struct cpu_wp cpu_wp_auto[] = { +static struct cpu_wp cpu_wp_auto_800[] = { { .pll_rate = 1000000000, .cpu_rate = 1000000000, @@ -86,13 +85,56 @@ static struct cpu_wp cpu_wp_auto[] = { .mfd = 2, .mfn = 1, .cpu_podf = 4, - .cpu_voltage = 850000,}, + .cpu_voltage = 900000,}, +}; + +static struct cpu_wp cpu_wp_auto_600[] = { + { + .pll_rate = 600000000, + .cpu_rate = 600000000, + .pdf = 0, + .mfi = 6, + .mfd = 3, + .mfn = 1, + .cpu_podf = 0, + .cpu_voltage = 1000000,}, + { + .pll_rate = 600000000, + .cpu_rate = 150000000, + .pdf = 3, + .mfi = 6, + .mfd = 3, + .mfn = 1, + .cpu_podf = 3, + .cpu_voltage = 950000,}, }; +static u32 ccwmx51_get_cpu_freq(void) +{ + u32 cpu_freq = 800000000; + + switch (system_serial_low & 0xff) { + case 4: + case 5: cpu_freq = 600000000; + num_cpu_wp = 2; + break; + } + + return cpu_freq; +} + struct cpu_wp *mx51_get_cpu_wp(int *wp) { + u32 cpu_clk_rate = ccwmx51_get_cpu_freq(); + *wp = num_cpu_wp; - return cpu_wp_auto; + + if (cpu_clk_rate == 800000000) { + return cpu_wp_auto_800; + } else if (cpu_clk_rate == 600000000) { + return cpu_wp_auto_600; + } + return NULL; } void mx51_set_num_cpu_wp(int num) @@ -121,7 +163,7 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, int total_mem = SZ_512M; int left_mem = 0; int gpu_mem = SZ_64M; - int fb_mem = SZ_32M; + int fb_mem = FB_MEM_SIZE; mxc_set_cpu_type(MXC_CPU_MX51); @@ -165,7 +207,9 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, fb_mem = 0; } mem_tag->u.mem.size = left_mem; - +#if defined(CONFIG_CCWMX51_DISP1) && defined(CONFIG_CCWMX51_DISP2) + fb_mem = fb_mem / 2; /* Divide the mem for between the displays */ +#endif /*reserve memory for gpu*/ gpu_device.resource[5].start = mem_tag->u.mem.start + left_mem; @@ -178,9 +222,17 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, gpu_device.resource[5].end + 1; mxcfb_resources[0].end = mxcfb_resources[0].start + fb_mem - 1; +#if defined(CONFIG_CCWMX51_DISP1) && defined(CONFIG_CCWMX51_DISP2) + mxcfb_resources[1].start = + mxcfb_resources[0].end + 1; + mxcfb_resources[1].end = + mxcfb_resources[1].start + fb_mem - 1; +#endif } else { mxcfb_resources[0].start = 0; mxcfb_resources[0].end = 0; + mxcfb_resources[1].start = 0; + mxcfb_resources[1].end = 0; } #endif } @@ -203,97 +255,20 @@ static void mxc_power_off(void) #endif } -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ccwmx51js_buttons[] = { - { - .gpio = IOMUX_TO_GPIO(MX51_PIN_GPIO1_8), - .code = BTN_1, - .desc = "Button 1", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = IOMUX_TO_GPIO(MX51_PIN_GPIO1_1), - .code = BTN_2, - .desc = "Button 2", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ccwmx51js_button_data = { - .buttons = ccwmx51js_buttons, - .nbuttons = ARRAY_SIZE(ccwmx51js_buttons), -}; - -static struct platform_device ccwmx51js_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ccwmx51js_button_data, - } -}; - -static void __init ccwmx51js_add_device_buttons(void) -{ - platform_device_register(&ccwmx51js_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - -#if defined(CONFIG_NEW_LEDS) - -/* - * GPIO LEDs - */ -static struct gpio_led_platform_data led_data; - -static struct gpio_led ccwmx51js_leds[] = { - { - .name = "LED1", - .gpio = IOMUX_TO_GPIO(MX51_PIN_NANDF_RB2), - .active_low = 1, - .default_trigger = "none", - }, - { - .name = "LED2", - .gpio = IOMUX_TO_GPIO(MX51_PIN_NANDF_RB1), - .active_low = 1, - .default_trigger = "none", - } -}; - -static struct platform_device ccwmx51js_gpio_leds_device = { - .name = "leds-gpio", - .id = -1, - .dev.platform_data = &led_data, -}; - -void __init ccwmx51js_gpio_leds(struct gpio_led *leds, int nr) -{ - if (!nr) - return; - - led_data.leds = leds; - led_data.num_leds = nr; - platform_device_register(&ccwmx51js_gpio_leds_device); -} - -#else -void __init at91_gpio_leds(struct gpio_led *leds, int nr) {} -#endif - /*! * Board specific initialization. */ static void __init mxc_board_init(void) { + /* Setup hwid information, passed through Serial ATAG */ + ccwmx51_set_mod_variant(system_serial_low & 0xff); + ccwmx51_set_mod_revision((system_serial_low >> 8) & 0xff); + ccwmx51_set_mod_sn(((system_serial_low << 8) & 0xff000000) | + ((system_serial_low >> 8) & 0x00ff0000) | + ((system_serial_high << 8) & 0x0000ff00) | + ((system_serial_high >> 8) & 0xff)); + + ccwmx51_swap_bi = system_serial_high >> 16; mxc_ipu_data.di_clk[0] = clk_get(NULL, "ipu_di0_clk"); mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di1_clk"); @@ -304,6 +279,7 @@ static void __init mxc_board_init(void) mxc_cpu_common_init(); mxc_register_gpios(); ccwmx51_io_init(); + ccwmx51_init_devices(); mxc_register_device(&mxc_wdt_device, NULL); mxc_register_device(&mxcspi1_device, &mxcspi1_data); @@ -330,21 +306,20 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_dvfs_per_device, &dvfs_per_data); mxc_register_device(&mxc_iim_device, NULL); mxc_register_device(&gpu_device, NULL); -#if defined(CONFIG_UIO_PDRV_GENIRQ) || defined(CONFIG_UIO_PDRV_GENIRQ_MODULE) - mxc_register_device(&mxc_gpu2d_device, &gpu2d_platform_data); +#if defined (CONFIG_MXC_SECURITY_SCC2) + mxc_register_device(&mxcscc_device, NULL); #endif mxc_register_device(&mxc_pwm1_device, NULL); mxc_register_device(&mxc_pwm_backlight_device, &mxc_pwm_backlight_data); -#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) - /* SD card detect irqs */ - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); - mxcsdhc3_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO_NAND); - mxcsdhc3_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO_NAND); - mxc_register_device(&mxcsdhc1_device, &mmc1_data); - mxc_register_device(&mxcsdhc3_device, &mmc3_data); -#endif +#ifdef CONFIG_ESDHCI_MXC_SELECT1 + ccwmx51_register_sdio(0); /* SDHC1 */ +#endif /* CONFIG_ESDHCI_MXC_SELECT1 */ +#if defined(CONFIG_ESDHCI_MXC_SELECT3) && \ + (!defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE)) + ccwmx51_register_sdio(2); /* SDHC3 */ +#endif /* CONFIG_ESDHCI_MXC_SELECT3 && !CONFIG_PATA_FSL && !CONFIG_PATA_FSL_MODULE */ + #if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) mxc_register_device(&mxc_fec_device, NULL); #endif @@ -356,6 +331,9 @@ static void __init mxc_board_init(void) || defined(CONFIG_MTD_NAND_MXC_V3_MODULE) mxc_register_device(&mxc_nandv2_mtd_device, &mxc_nand_data); #endif +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) + mxc_register_device(&pata_fsl_device, &ata_data); +#endif #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) mxc_register_device(&smsc911x_device, &ccwmx51_smsc9118); #endif @@ -368,23 +346,23 @@ static void __init mxc_board_init(void) mx5_usbh1_init(); #endif mx5_usb_dr_init(); -#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) - mxc_register_device(&lcd_pdev, plcd_platform_data); - mxc_fb_devices[0].num_resources = ARRAY_SIZE(mxcfb_resources); - mxc_fb_devices[0].resource = mxcfb_resources; - mxc_register_device(&mxc_fb_devices[0], &mx51_fb_data[0]); -// mxc_register_device(&mxc_fb_devices[1], &mx51_fb_data[1]); -// mxc_register_device(&mxc_fb_devices[2], NULL); -#endif +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) && \ + (defined(CONFIG_CCWMX51_DISP0) || defined(CONFIG_CCWMX51_DISP1)) + ccwmx51_init_fb(); +#endif /* defined(CONFIG_FB_MXC_SYNC_PANEL) || ... */ #ifdef CONFIG_MXC_PMIC_MC13892 ccwmx51_init_mc13892(); /* Configure PMIC irq line */ set_irq_type(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), IRQ_TYPE_EDGE_BOTH); #endif - ccwmx51js_add_device_buttons(); - ccwmx51js_gpio_leds(ccwmx51js_leds, ARRAY_SIZE(ccwmx51js_leds)); +#ifdef CONFIG_SYSFS + ccwmx51_create_sysfs_entries(); +#endif +#ifdef CONFIG_CCWMX51_SECOND_TOUCH + ccwmx51_init_2nd_touch(); +#endif pm_power_off = mxc_power_off; } @@ -394,9 +372,9 @@ static void __init ccwmx51_timer_init(void) /* Change the CPU voltages for TO2*/ if (cpu_is_mx51_rev(CHIP_REV_2_0) <= 1) { - cpu_wp_auto[0].cpu_voltage = 1175000; - cpu_wp_auto[1].cpu_voltage = 1100000; - cpu_wp_auto[2].cpu_voltage = 1000000; + cpu_wp_auto_800[0].cpu_voltage = 1175000; + cpu_wp_auto_800[1].cpu_voltage = 1100000; + cpu_wp_auto_800[2].cpu_voltage = 1000000; } mx51_clocks_init(32768, 24000000, 22579200, 24576000); @@ -409,14 +387,30 @@ static struct sys_timer mxc_timer = { .init = ccwmx51_timer_init, }; -MACHINE_START(CCWMX51JS, "ConnectCore Wi-i.MX51 on a JSK board") +#if defined(CONFIG_MACH_CCWMX51JS) +MACHINE_START(CCWMX51JS, "ConnectCore Wi-i.MX51"BOARD_NAME) + /* Maintainer: Digi International, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mx5_map_io, + .init_irq = mx5_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END +#endif /* CONFIG_MACH_CCWMX51JS */ + +#if defined(CONFIG_MACH_CCMX51JS) +MACHINE_START(CCMX51JS, "ConnectCore i.MX51"BOARD_NAME) /* Maintainer: Digi International, Inc. */ - .phys_io = AIPS1_BASE_ADDR, - .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, - .boot_params = PHYS_OFFSET + 0x100, - .fixup = fixup_mxc_board, - .map_io = mx5_map_io, - .init_irq = mx5_init_irq, - .init_machine = mxc_board_init, - .timer = &mxc_timer, + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mx5_map_io, + .init_irq = mx5_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, MACHINE_END +#endif /* CONFIG_MACH_CCMX51JS */ diff --git a/arch/arm/mach-mx5/mx51_ccwmx51js_gpio.c b/arch/arm/mach-mx5/mx51_ccwmx51js_gpio.c index 51b9301a3547..b626605bd8fa 100644 --- a/arch/arm/mach-mx5/mx51_ccwmx51js_gpio.c +++ b/arch/arm/mach-mx5/mx51_ccwmx51js_gpio.c @@ -21,8 +21,7 @@ #include "iomux.h" #include "mx51_pins.h" - -static void ccwmx51_mmc2_gpio_active(void); +#include "board-ccwmx51.h" /** @@ -30,8 +29,8 @@ static void ccwmx51_mmc2_gpio_active(void); */ #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_ext_eth_pins[] = { - {MX51_PIN_EIM_CS5, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER | PAD_CTL_DRV_MEDIUM), }, + {MX51_PIN_EIM_CS5, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER | PAD_CTL_DRV_MEDIUM), }, {MX51_PIN_EIM_OE, IOMUX_CONFIG_ALT0,}, {MX51_PIN_EIM_DA0, IOMUX_CONFIG_ALT0,}, {MX51_PIN_EIM_DA1, IOMUX_CONFIG_ALT0,}, @@ -62,7 +61,7 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_ext_eth_pins[] = { #endif #if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) -static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_mmc_pins[] = { +static struct mxc_iomux_pin_cfg ccwmx51_iomux_mmc1_pins[] = { /* SDHC1*/ { MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, @@ -94,11 +93,49 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_mmc_pins[] = { (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), }, +#ifdef CONFIG_JSCCWMX51_V1 { MX51_PIN_GPIO1_0, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), }, +#endif +}; + +#ifdef CONFIG_MACH_CCWMX51JS +/* IOMUX settings, for the wireless interface on Wi-i.MX51 module */ +#define SD2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH | \ + PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | \ + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST) +static struct mxc_iomux_pin_cfg ccwmx51_iomux_mmc2_pins[] = { + /* SDHC2*/ + { + MX51_PIN_SD2_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, + { + MX51_PIN_SD2_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, + { + MX51_PIN_SD2_DATA0, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, + { + MX51_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, + { + MX51_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, + { + MX51_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + SD2_PAD_CFG, + }, +}; +#endif +static struct mxc_iomux_pin_cfg ccwmx51_iomux_mmc3_pins[] = { /* SDHC3*/ { MX51_PIN_NANDF_RDY_INT, IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION, @@ -137,6 +174,56 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_mmc_pins[] = { (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), }, }; + +void gpio_sdhc_active(int interface) +{ + int i; + + switch (interface) { + case 0: + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_mmc1_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_mmc1_pins[i].pin, + ccwmx51_iomux_mmc1_pins[i].mux_mode); + if (ccwmx51_iomux_mmc1_pins[i].pad_cfg) + mxc_iomux_set_pad(ccwmx51_iomux_mmc1_pins[i].pin, + ccwmx51_iomux_mmc1_pins[i].pad_cfg); + if (ccwmx51_iomux_mmc1_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_iomux_mmc1_pins[i].in_select, + ccwmx51_iomux_mmc1_pins[i].in_mode); + } + break; + case 1: +#ifdef CONFIG_MACH_CCWMX51JS + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_mmc2_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_mmc2_pins[i].pin, + ccwmx51_iomux_mmc2_pins[i].mux_mode); + if (ccwmx51_iomux_mmc2_pins[i].pad_cfg) + mxc_iomux_set_pad(ccwmx51_iomux_mmc2_pins[i].pin, + ccwmx51_iomux_mmc2_pins[i].pad_cfg); + if (ccwmx51_iomux_mmc2_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_iomux_mmc2_pins[i].in_select, + ccwmx51_iomux_mmc2_pins[i].in_mode); + } +#endif + break; + + case 2: + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_mmc3_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_mmc3_pins[i].pin, + ccwmx51_iomux_mmc3_pins[i].mux_mode); + if (ccwmx51_iomux_mmc3_pins[i].pad_cfg) + mxc_iomux_set_pad(ccwmx51_iomux_mmc3_pins[i].pin, + ccwmx51_iomux_mmc3_pins[i].pad_cfg); + if (ccwmx51_iomux_mmc3_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_iomux_mmc3_pins[i].in_select, + ccwmx51_iomux_mmc3_pins[i].in_mode); + } + break; + } +} +EXPORT_SYMBOL(gpio_sdhc_active); +void gpio_sdhc_inactive(int module) {} +EXPORT_SYMBOL(gpio_sdhc_inactive); #endif #if defined(CONFIG_USB_EHCI_ARC_H1) || defined(CONFIG_USB_EHCI_ARC_H1_MODULE) @@ -202,122 +289,218 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_usbh1_pins[] = { PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), }, { /* USBH PHY RESET */ - MX51_PIN_DISPB2_SER_RS, IOMUX_CONFIG_GPIO, + MX51_PIN_DISPB2_SER_RS, IOMUX_CONFIG_ALT4, (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + MUX_IN_GPIO3_IPP_IND_G_IN_8_SELECT_INPUT, INPUT_CTL_PATH1 }, }; #endif #if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) -static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_video1_pins[] = { - { /* DISP1 DAT0 */ +#if defined(CONFIG_CCWMX51_DISP0) +#define DISP1_PAD0 (PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST) +static struct mxc_iomux_pin_cfg ccwmx51_iomux_video1_pins[] = { + { /* DISP1 DAT0 */ MX51_PIN_DISP1_DAT0, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT1 */ MX51_PIN_DISP1_DAT1, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT2 */ MX51_PIN_DISP1_DAT2, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT3 */ MX51_PIN_DISP1_DAT3, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT4 */ MX51_PIN_DISP1_DAT4, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT5 */ MX51_PIN_DISP1_DAT5, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT6 */ MX51_PIN_DISP1_DAT6, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT7 */ MX51_PIN_DISP1_DAT7, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT8 */ MX51_PIN_DISP1_DAT8, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT9 */ MX51_PIN_DISP1_DAT9, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT10 */ MX51_PIN_DISP1_DAT10, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT11 */ MX51_PIN_DISP1_DAT11, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT12 */ MX51_PIN_DISP1_DAT12, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT13 */ MX51_PIN_DISP1_DAT13, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT14 */ MX51_PIN_DISP1_DAT14, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT15 */ MX51_PIN_DISP1_DAT15, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT16 */ MX51_PIN_DISP1_DAT16, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT17 */ MX51_PIN_DISP1_DAT17, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT18 */ MX51_PIN_DISP1_DAT18, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT19 */ MX51_PIN_DISP1_DAT19, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT20 */ MX51_PIN_DISP1_DAT20, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + DISP1_PAD0, }, { /* DISP1 DAT21 */ - MX51_PIN_DISP1_DAT21, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, - { /* DISP1 DAT22 */ - MX51_PIN_DISP1_DAT22, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), + MX51_PIN_DISP1_DAT21, IOMUX_CONFIG_ALT0, + DISP1_PAD0, + }, +#if !defined(CONFIG_CCWMX51_DISP1) + { /* DISP1 DAT22 */ + MX51_PIN_DISP1_DAT22, IOMUX_CONFIG_ALT0, + DISP1_PAD0, }, { /* DISP1 DAT23 */ - MX51_PIN_DISP1_DAT23, IOMUX_CONFIG_ALT0, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, - { /* LCD1 Power Enable, as gpio */ - MX51_PIN_DI1_PIN11, IOMUX_CONFIG_GPIO, - (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | - PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), - }, + MX51_PIN_DISP1_DAT23, IOMUX_CONFIG_ALT0, + DISP1_PAD0, + }, +#endif }; #endif +#if defined(CONFIG_CCWMX51_DISP1) +#define DISP2_PAD0 (PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST) +static struct mxc_iomux_pin_cfg ccwmx51_iomux_video2_pins[] = { + /* This interface can be enabled only if the FEC interface is disabled */ + { /* DISP2 DAT0 */ + MX51_PIN_DISP2_DAT0, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT1 */ + MX51_PIN_DISP2_DAT1, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT2 */ + MX51_PIN_DISP2_DAT2, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT3 */ + MX51_PIN_DISP2_DAT3, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT4 */ + MX51_PIN_DISP2_DAT4, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT5 */ + MX51_PIN_DISP2_DAT5, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT6 */ + MX51_PIN_DISP2_DAT6, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT7 */ + MX51_PIN_DISP2_DAT7, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT8 */ + MX51_PIN_DISP2_DAT8, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT9 */ + MX51_PIN_DISP2_DAT9, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT10 */ + MX51_PIN_DISP2_DAT10, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT11 */ + MX51_PIN_DISP2_DAT11, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT12 */ + MX51_PIN_DISP2_DAT12, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT13 */ + MX51_PIN_DISP2_DAT13, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT14 */ + MX51_PIN_DISP2_DAT14, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DAT15 */ + MX51_PIN_DISP2_DAT15, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 16 (also DISP1 DAT22) */ + MX51_PIN_DISP1_DAT22, IOMUX_CONFIG_ALT5, + DISP2_PAD0, + }, + { /* DISP2 17 (also DISP1 DAT23) */ + MX51_PIN_DISP1_DAT23, IOMUX_CONFIG_ALT5, + DISP2_PAD0, + }, + { /* DISP2 HSYNC */ + MX51_PIN_DI2_PIN2, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 VSYNC */ + MX51_PIN_DI2_PIN3, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 PCLK */ + MX51_PIN_DI2_DISP_CLK, IOMUX_CONFIG_ALT0, + DISP2_PAD0, + }, + { /* DISP2 DRDY */ + MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4, + DISP2_PAD0, + }, +}; +#endif +#endif + #if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_i2c_pins[] = { -#ifdef CONFIG_I2C_MXC_SELECT1 +#if defined (CONFIG_I2C_MXC_SELECT1) { MX51_PIN_SD2_CMD, IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION, (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_HYS_ENABLE | @@ -376,28 +559,6 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_devices_pins[] = { PAD_CTL_100K_PU | PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST), }, #endif - /* Push Buttons */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) - { /* Button 1 */ - MX51_PIN_GPIO1_8, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, - { /* Button 2 */ - MX51_PIN_GPIO1_1, IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, -#endif - /* LEDs */ -#if defined(CONFIG_NEW_LEDS) - { /* LED1 */ - MX51_PIN_NANDF_RB2, IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, - { /* LED2 */ - MX51_PIN_NANDF_RB1, IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION, - (PAD_CTL_HYS_NONE | PAD_CTL_DRV_LOW | PAD_CTL_SRE_FAST), - }, -#endif }; #if defined(CONFIG_SND_SOC_WM8753) || defined(CONFIG_SND_SOC_WM8753_MODULE) @@ -429,6 +590,93 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_audio_pins[] = { }; #endif +#if defined CONFIG_VIDEO_MXC_IPU_CAMERA +static struct mxc_iomux_pin_cfg __initdata ccwmx51_camera_pins[] = { + /* CSI0 camera interface 1 */ + { + MX51_PIN_CSI1_D12, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D13, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D14, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D15, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D16, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D17, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D18, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D19, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + { + MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + /* Configure GPIO3_13 as RESET for camera 1 */ + { + MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_NONE | PAD_CTL_DRV_MEDIUM | PAD_CTL_SRE_FAST), + }, + /* CSI2 camera interface 2 */ + { + MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D14, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D15, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D16, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D17, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D18, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_D19, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI2_VSYNC, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + { + MX51_PIN_CSI2_HSYNC, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + { + MX51_PIN_CSI2_PIXCLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + /* Configure GPIO3_7 as RESET for camera 2 */ + { + MX51_PIN_DISPB2_SER_CLK, IOMUX_CONFIG_ALT4, + (PAD_CTL_HYS_NONE | PAD_CTL_DRV_MEDIUM | PAD_CTL_SRE_FAST | IOMUX_CONFIG_SION), + MUX_IN_GPIO3_IPP_IND_G_IN_7_SELECT_INPUT, + INPUT_CTL_PATH1 + }, +}; +#endif /* #if defined CONFIG_VIDEO_MXC_IPU_CAMERA */ + #if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) static struct mxc_iomux_pin_cfg __initdata ccwmx51_cspi_pins[] = { #ifdef CONFIG_SPI_MXC_SELECT1 @@ -453,6 +701,29 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_cspi_pins[] = { (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE), }, + +#if defined(CONFIG_JSCCWMX51_V1) + { /* TS CS for LCD1 on CCWMX51 EAK */ + MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PUE_KEEPER | PAD_CTL_HYS_NONE), + MUX_IN_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT,INPUT_CTL_PATH1 + }, + { /* TS CS for LCD2 on CCWMX51 EAK */ + MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT3, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_NONE), + MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT,INPUT_CTL_PATH1 + }, +#else + { /* TS CS for LCD1 and LCD2 on CCWMX51 JSK */ + MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT3, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_NONE), + MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT,INPUT_CTL_PATH1 + }, +#endif + #ifdef CONFIG_SPI_MXC_SELECT1_SS1 { /* SS1 */ MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_GPIO, @@ -461,7 +732,7 @@ static struct mxc_iomux_pin_cfg __initdata ccwmx51_cspi_pins[] = { }, #endif #endif -#ifdef CONFIG_SPI_MXC_SELECT2 +#if defined(CONFIG_SPI_MXC_SELECT2) && (!defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE)) /* ECSPI2 */ { /* SCLK */ MX51_PIN_NANDF_RB2, IOMUX_CONFIG_ALT2, @@ -534,17 +805,37 @@ void ccwmx51_gpio_spi_chipselect_active(int busnum, int ssb_pol, int chipselect) { u8 mask = 0x1 << (chipselect - 1); + /* Deassert/Assert the different CS lines for the different buses */ switch (busnum) { case 1: switch (chipselect) { case 0x1: + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), + (ssb_pol & mask) ? 0 : 1); +#ifdef CONFIG_CCWMX51_SECOND_TOUCH + gpio_set_value(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 1); +#endif gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), (ssb_pol & mask) ? 1 : 0); break; case 0x2: + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), + (ssb_pol & mask) ? 0 : 1); +#ifdef CONFIG_CCWMX51_SECOND_TOUCH + gpio_set_value(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 1); +#endif gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), (ssb_pol & mask) ? 1 : 0); break; +#ifdef CONFIG_CCWMX51_SECOND_TOUCH + case 0x4: + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0), + (ssb_pol & mask) ? 0 : 1); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), + (ssb_pol & mask) ? 0 : 1); + gpio_set_value(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 0); + break; +#endif default: break; } @@ -573,6 +864,11 @@ void ccwmx51_gpio_spi_chipselect_inactive(int busnum, int ssb_pol, gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS1), (ssb_pol & mask) ? 0 : 1); break; +#ifdef CONFIG_CCWMX51_SECOND_TOUCH + case 0x4: + gpio_set_value(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 1); + break; +#endif default: break; } @@ -581,20 +877,159 @@ void ccwmx51_gpio_spi_chipselect_inactive(int busnum, int ssb_pol, case 3: default: break; - } + } } EXPORT_SYMBOL(ccwmx51_gpio_spi_chipselect_inactive); - #endif /* defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) */ -void __init ccwmx51_io_init(void) +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) +static struct mxc_iomux_pin_cfg ata_iomux_pins[] = { + { + MX51_PIN_NANDF_ALE, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_CLE, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_RB0, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_GPIO_NAND, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_RB1, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D0, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D1, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D2, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D3, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D4, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D5, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D6, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D7, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D8, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D9, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D10, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D11, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D13, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D14, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH), + }, +}; + +void gpio_ata_active(void) { int i; + for (i = 0; i < ARRAY_SIZE(ata_iomux_pins); i++) { + mxc_request_iomux(ata_iomux_pins[i].pin, + ata_iomux_pins[i].mux_mode); + if (ata_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(ata_iomux_pins[i].pin, + ata_iomux_pins[i].pad_cfg); + if (ata_iomux_pins[i].in_select) + mxc_iomux_set_input(ata_iomux_pins[i].in_select, + ata_iomux_pins[i].in_mode); + } +} +EXPORT_SYMBOL(gpio_ata_active); +void gpio_ata_inactive(void) {} +EXPORT_SYMBOL(gpio_ata_inactive); +#endif /* CONFIG_PATA_FSL || CONFIG_PATA_FSL_MODULE */ + +void __init ccwmx51_io_init(void) +{ + int i; + #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_ext_eth_pins); i++) { - mxc_request_iomux(ccwmx51_iomux_ext_eth_pins[i].pin, - ccwmx51_iomux_ext_eth_pins[i].mux_mode); + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_ext_eth_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_ext_eth_pins[i].pin, + ccwmx51_iomux_ext_eth_pins[i].mux_mode); if (ccwmx51_iomux_ext_eth_pins[i].pad_cfg) mxc_iomux_set_pad(ccwmx51_iomux_ext_eth_pins[i].pin, ccwmx51_iomux_ext_eth_pins[i].pad_cfg); @@ -604,17 +1039,40 @@ void __init ccwmx51_io_init(void) } #endif -#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_mmc_pins); i++) { - mxc_request_iomux(ccwmx51_iomux_mmc_pins[i].pin, - ccwmx51_iomux_mmc_pins[i].mux_mode); - if (ccwmx51_iomux_mmc_pins[i].pad_cfg) - mxc_iomux_set_pad(ccwmx51_iomux_mmc_pins[i].pin, - ccwmx51_iomux_mmc_pins[i].pad_cfg); - if (ccwmx51_iomux_mmc_pins[i].in_select) - mxc_iomux_set_input(ccwmx51_iomux_mmc_pins[i].in_select, - ccwmx51_iomux_mmc_pins[i].in_mode); +#if defined CONFIG_VIDEO_MXC_IPU_CAMERA + for (i = 0; i < ARRAY_SIZE(ccwmx51_camera_pins); i++) { + mxc_request_iomux(ccwmx51_camera_pins[i].pin, + ccwmx51_camera_pins[i].mux_mode); + if (ccwmx51_camera_pins[i].pad_cfg) + mxc_iomux_set_pad(ccwmx51_camera_pins[i].pin, + ccwmx51_camera_pins[i].pad_cfg); + if (ccwmx51_camera_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_camera_pins[i].in_select, + ccwmx51_camera_pins[i].in_mode); } + + /* Configure non muxed pins */ + mxc_iomux_set_pad(MX51_PIN_CSI1_PIXCLK,PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW); + mxc_iomux_set_pad(MX51_PIN_CSI2_PIXCLK,PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW); + mxc_iomux_set_pad(MX51_PIN_CSI1_MCLK,PAD_CTL_DRV_HIGH | PAD_CTL_SRE_SLOW); + + /* Camera 1 reset */ + gpio_request(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), "gpio3_13"); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0); + // Take camera out of reset + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0); + msleep(100); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 1); + msleep(100); + + /* Camera 2 reset */ + gpio_request(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_CLK), "gpio3_7"); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_CLK), 0); + // Take camera out of reset + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_CLK), 0); + msleep(100); + gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_CLK), 1); + msleep(100); #endif #if defined(CONFIG_USB_EHCI_ARC_H1) || defined(CONFIG_USB_EHCI_ARC_H1_MODULE) @@ -630,25 +1088,9 @@ void __init ccwmx51_io_init(void) } #endif -#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_video1_pins); i++) { - mxc_request_iomux(ccwmx51_iomux_video1_pins[i].pin, - ccwmx51_iomux_video1_pins[i].mux_mode); - if (ccwmx51_iomux_video1_pins[i].pad_cfg) - mxc_iomux_set_pad(ccwmx51_iomux_video1_pins[i].pin, - ccwmx51_iomux_video1_pins[i].pad_cfg); - if (ccwmx51_iomux_video1_pins[i].in_select) - mxc_iomux_set_input(ccwmx51_iomux_video1_pins[i].in_select, - ccwmx51_iomux_video1_pins[i].in_mode); - } - /* LCD Power Enable */ - gpio_request(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), "gpio3_0"); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), 0); -#endif - #if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_i2c_pins); i++) { - mxc_request_iomux(ccwmx51_iomux_i2c_pins[i].pin, + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_i2c_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_i2c_pins[i].pin, ccwmx51_iomux_i2c_pins[i].mux_mode); if (ccwmx51_iomux_i2c_pins[i].pad_cfg) mxc_iomux_set_pad(ccwmx51_iomux_i2c_pins[i].pin, @@ -695,16 +1137,18 @@ void __init ccwmx51_io_init(void) #endif #ifndef CONFIG_SPI_MXC_SELECT2 - /* Configure as GPIO to be used to read LED status */ - mxc_config_iomux(MX51_PIN_NANDF_RB2,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); - mxc_iomux_set_pad(MX51_PIN_NANDF_RB2,PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU); - mxc_config_iomux(MX51_PIN_NANDF_RB1,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); - mxc_iomux_set_pad(MX51_PIN_NANDF_RB1,PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU); + /* Configure as GPIO to be used to read LED status */ + mxc_config_iomux(MX51_PIN_NANDF_RB2,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_iomux_set_pad(MX51_PIN_NANDF_RB2,PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU); +#if !defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE) + mxc_config_iomux(MX51_PIN_NANDF_RB1,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_iomux_set_pad(MX51_PIN_NANDF_RB1,PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU); +#endif /* !defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE) */ #endif #endif - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_devices_pins); i++) { + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_devices_pins); i++) { mxc_request_iomux(ccwmx51_iomux_devices_pins[i].pin, ccwmx51_iomux_devices_pins[i].mux_mode); if (ccwmx51_iomux_devices_pins[i].pad_cfg) @@ -727,67 +1171,91 @@ void __init ccwmx51_io_init(void) gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_RS), 1); #endif -#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) - /* For the wireless module */ - ccwmx51_mmc2_gpio_active(); + /* Configure user key 1 as GPIO */ +#if defined(CONFIG_JSCCWMX51_V2) + mxc_config_iomux(MX51_PIN_DISPB2_SER_DIO,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT,INPUT_CTL_PATH1); #endif -} -#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) -/* IOMUX settings, for the wireless interface */ -static struct mxc_iomux_pin_cfg __initdata ccwmx51_iomux_mmc2_pins[] = { - /* SDHC2*/ - { - MX51_PIN_SD2_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, - { - MX51_PIN_SD2_CLK, IOMUX_CONFIG_ALT0, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, - { - MX51_PIN_SD2_DATA0, IOMUX_CONFIG_ALT0, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, - { - MX51_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, - { - MX51_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, - { - MX51_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0, - (PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | - PAD_CTL_47K_PU | PAD_CTL_SRE_FAST), - }, -}; + /* Configure Digital IO as GPIO */ +#if defined(CONFIG_JSCCWMX51_V1) +#if !defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE) + mxc_config_iomux(MX51_PIN_NANDF_CS4,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_CS5,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_CS6,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); +#endif +#if !defined(CONFIG_MMC_IMX_ESDHCI) && !defined(CONFIG_MMC_IMX_ESDHCI_MODULE) + mxc_config_iomux(MX51_PIN_NANDF_CS7,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); +#endif -static void ccwmx51_mmc2_gpio_active(void) -{ - int i; + mxc_config_iomux(MX51_PIN_DISPB2_SER_DIN,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT,INPUT_CTL_PATH1); + mxc_config_iomux(MX51_PIN_DISPB2_SER_DIO,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT,INPUT_CTL_PATH1); +#if !defined (CONFIG_VIDEO_MXC_IPU_CAMERA) + mxc_config_iomux(MX51_PIN_DISPB2_SER_CLK,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_7_SELECT_INPUT,INPUT_CTL_PATH1); +#endif +#if !defined(CONFIG_USB_EHCI_ARC_H1) && !defined(CONFIG_USB_EHCI_ARC_H1_MODULE) + mxc_config_iomux(MX51_PIN_DISPB2_SER_RS,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_8_SELECT_INPUT,INPUT_CTL_PATH1); +#endif +#endif + +#if defined(CONFIG_JSCCWMX51_V2) +#if !defined (CONFIG_SPI_MXC_SELECT2) + mxc_config_iomux(MX51_PIN_NANDF_RB3,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); +#endif + +#if !defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE) + mxc_config_iomux(MX51_PIN_NANDF_CS2,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_CS4,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_CS5,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_CS6,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); +#endif + +#if !defined(CONFIG_SPI_MXC_SELECT2) || (!defined(CONFIG_PATA_FSL) && !defined(CONFIG_PATA_FSL_MODULE)) + mxc_config_iomux(MX51_PIN_NANDF_RB1,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); + mxc_config_iomux(MX51_PIN_NANDF_RB2,IOMUX_CONFIG_ALT3 | IOMUX_CONFIG_SION); +#endif + mxc_config_iomux(MX51_PIN_DISPB2_SER_DIO,IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT,INPUT_CTL_PATH1); +#endif - for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_mmc2_pins); i++) { - mxc_request_iomux(ccwmx51_iomux_mmc2_pins[i].pin, - ccwmx51_iomux_mmc2_pins[i].mux_mode); - if (ccwmx51_iomux_mmc2_pins[i].pad_cfg) - mxc_iomux_set_pad(ccwmx51_iomux_mmc2_pins[i].pin, - ccwmx51_iomux_mmc2_pins[i].pad_cfg); - if (ccwmx51_iomux_mmc2_pins[i].in_select) - mxc_iomux_set_input(ccwmx51_iomux_mmc2_pins[i].in_select, - ccwmx51_iomux_mmc2_pins[i].in_mode); - } } -void ccwmx51_mmc2_gpio_inactive(void) +#ifdef CONFIG_CCWMX51_SECOND_TOUCH +void ccwmx51_2nd_touch_gpio_init(void) { + /* Second touch interface interrupt line */ + mxc_request_iomux(SECOND_TS_IRQ_PIN, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(SECOND_TS_IRQ_PIN, PAD_CTL_SRE_FAST | PAD_CTL_HYS_ENABLE); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT, INPUT_CTL_PATH1); + + /* SECOND_TS_SPI_SS_PIN depends on configuration, check board-ccwmx51 to see options */ + mxc_request_iomux(SECOND_TS_SPI_SS_PIN, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(SECOND_TS_SPI_SS_PIN, PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | + PAD_CTL_47K_PU | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE); + + /* Configure the Slave Select signal as gpio, to workaround a silicon errata */ + gpio_request(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), "ts2_spi_ss"); + gpio_direction_output(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 1); + gpio_set_value(IOMUX_TO_GPIO(SECOND_TS_SPI_SS_PIN), 1); + + /* Configure 2nd touch interrupt line */ + gpio_request(IOMUX_TO_GPIO(SECOND_TS_IRQ_PIN), "ts2_irq"); + gpio_direction_input(IOMUX_TO_GPIO(SECOND_TS_IRQ_PIN)); + + /** + * Configure gpio line to detect which touch is connected to each + * display interface + */ + mxc_config_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_DI1_D1_CS, PAD_CTL_SRE_FAST | PAD_CTL_HYS_ENABLE); + mxc_iomux_set_input(MUX_IN_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT, INPUT_CTL_PATH1); } +#else +void ccwmx51_2nd_touch_gpio_init(void) {} #endif #if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) @@ -808,8 +1276,24 @@ void gpio_uart_active(int port, int no_irda) mxc_iomux_set_pad(MX51_PIN_UART1_TXD, SERIAL_PORT_PAD); mxc_iomux_set_input(MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, INPUT_CTL_PATH0); - /* TODO enable CTS/RTS if selected */ -#endif +#if defined(CONFIG_UART1_CTS_RTS_ENABLED) || defined(CONFIG_UART1_FULL_UART_ENABLED) + mxc_request_iomux(MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0); + mxc_request_iomux(MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_UART1_CTS, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_UART1_RTS, SERIAL_PORT_PAD); + mxc_iomux_set_input(MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, INPUT_CTL_PATH0); +#endif /* CONFIG_UART1_CTS_RTS_ENABLED */ +#ifdef CONFIG_UART1_FULL_UART_ENABLED + mxc_request_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT1); /* DCD */ + mxc_request_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT1); /* RI */ + mxc_request_iomux(MX51_PIN_UART3_TXD, IOMUX_CONFIG_ALT0); /* DSR */ + mxc_request_iomux(MX51_PIN_UART3_RXD, IOMUX_CONFIG_ALT0); /* DTR */ + mxc_iomux_set_pad(MX51_PIN_KEY_COL5, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_KEY_COL4, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_UART3_TXD, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_UART3_RXD, SERIAL_PORT_PAD); +#endif /* CONFIG_UART1_FULL_UART_ENABLED */ +#endif /* CONFIG_UART1_ENABLED */ break; case 1: /* UART 2 IOMUX Configs */ @@ -820,8 +1304,16 @@ void gpio_uart_active(int port, int no_irda) mxc_iomux_set_pad(MX51_PIN_UART2_TXD, SERIAL_PORT_PAD); mxc_iomux_set_input(MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, INPUT_CTL_PATH2); - /* TODO enable CTS/RTS if selected */ -#endif +#ifdef CONFIG_UART2_CTS_RTS_ENABLED +#if !defined(CONFIG_USB_EHCI_ARC_H1) && !defined(CONFIG_USB_EHCI_ARC_H1_MODULE) + mxc_request_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT1); /* CTS */ + mxc_request_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT1); /* RTS */ + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA0, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_USBH1_DATA3, SERIAL_PORT_PAD); + mxc_iomux_set_input(MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, INPUT_CTL_PATH5); +#endif /* CONFIG_USB_EHCI_ARC_H1 && CONFIG_USB_EHCI_ARC_H1_MODULE */ +#endif /* CONFIG_UART2_CTS_RTS_ENABLED */ +#endif /* CONFIG_UART2_CTS_RTS_ENABLED */ break; case 2: /* UART 3 IOMUX Configs */ #ifdef CONFIG_UART3_ENABLED @@ -831,15 +1323,19 @@ void gpio_uart_active(int port, int no_irda) mxc_iomux_set_pad(MX51_PIN_UART3_TXD, SERIAL_PORT_PAD); mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT, INPUT_CTL_PATH4); - /* TODO enable CTS/RTS if selected */ -#endif +#ifdef CONFIG_UART3_CTS_RTS_ENABLED + mxc_request_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT2); /* CTS */ + mxc_request_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT2); /* RTS */ + mxc_iomux_set_pad(MX51_PIN_KEY_COL5, SERIAL_PORT_PAD); + mxc_iomux_set_pad(MX51_PIN_KEY_COL4, SERIAL_PORT_PAD); + mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT, INPUT_CTL_PATH4); +#endif /* CONFIG_UART3_CTS_RTS_ENABLED */ +#endif /* CONFIG_UART3_ENABLED */ break; default: break; } - } - #else void gpio_uart_active(int port, int no_irda) {} #endif @@ -847,5 +1343,74 @@ void gpio_uart_inactive(int port, int no_irda) {} EXPORT_SYMBOL(gpio_uart_active); EXPORT_SYMBOL(gpio_uart_inactive); +void gpio_video_active(int vif, u32 pad) +{ + int i; + +#if defined(CONFIG_CCWMX51_DISP0) + if (vif == 0) { + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_video1_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_video1_pins[i].pin, + ccwmx51_iomux_video1_pins[i].mux_mode); + + if (ccwmx51_iomux_video1_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_iomux_video1_pins[i].in_select, + ccwmx51_iomux_video1_pins[i].in_mode); + if (!pad) + mxc_iomux_set_pad(ccwmx51_iomux_video1_pins[i].pin, + ccwmx51_iomux_video1_pins[i].pad_cfg); + else + mxc_iomux_set_pad(ccwmx51_iomux_video1_pins[i].pin, + pad); + } + + /* LCD1 Power Enable, as gpio */ + mxc_request_iomux(MX51_PIN_DI1_PIN11, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_DI1_PIN11, + PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE); + gpio_request(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), "gpio3_0"); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN11), 0); + } +#endif +#if defined(CONFIG_CCWMX51_DISP1) + if (vif == 1) { + for (i = 0; i < ARRAY_SIZE(ccwmx51_iomux_video2_pins); i++) { + mxc_request_iomux(ccwmx51_iomux_video2_pins[i].pin, + ccwmx51_iomux_video2_pins[i].mux_mode); + + if (ccwmx51_iomux_video2_pins[i].in_select) + mxc_iomux_set_input(ccwmx51_iomux_video2_pins[i].in_select, + ccwmx51_iomux_video2_pins[i].in_mode); + if (!pad) + mxc_iomux_set_pad(ccwmx51_iomux_video2_pins[i].pin, + ccwmx51_iomux_video2_pins[i].pad_cfg); + else + mxc_iomux_set_pad(ccwmx51_iomux_video2_pins[i].pin, + pad); + } + + /* LCD2 Power Enable, as gpio */ +#ifdef CONFIG_JSCCWMX51_V1 + mxc_request_iomux(MX51_PIN_DI2_PIN4, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_DI2_PIN4, pad); +#else + mxc_request_iomux(MX51_PIN_DI1_PIN12, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_DI1_PIN12, + PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_47K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE); + + gpio_request(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN12), "gpio3_1"); + gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_DI1_PIN12), 0); +#endif + } +#endif /* defined(CONFIG_CCWMX51_DISP1) */ +} + +void gpio_video_inactive(int vif, u32 pad) +{ +} +EXPORT_SYMBOL(gpio_video_active); +EXPORT_SYMBOL(gpio_video_inactive); diff --git a/arch/arm/mach-mx5/mx53_evk.c b/arch/arm/mach-mx5/mx53_evk.c index 104e5f93d6e9..443857c76a84 100644 --- a/arch/arm/mach-mx5/mx53_evk.c +++ b/arch/arm/mach-mx5/mx53_evk.c @@ -36,13 +36,14 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> #include <linux/mtd/partitions.h> -#include <linux/spi/flash.h> #include <linux/regulator/consumer.h> #include <linux/pmic_external.h> #include <linux/pmic_status.h> #include <linux/ipu.h> #include <linux/mxcfb.h> #include <linux/pwm_backlight.h> +#include <linux/fec.h> +#include <linux/ahci_platform.h> #include <mach/common.h> #include <mach/hardware.h> #include <asm/irq.h> @@ -51,11 +52,11 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/mach/keypad.h> +#include <asm/mach/flash.h> #include <mach/memory.h> #include <mach/gpio.h> #include <mach/mmc.h> #include <mach/mxc_dvfs.h> -#include "board-mx53_evk.h" #include "iomux.h" #include "mx53_pins.h" #include "crm_regs.h" @@ -69,6 +70,7 @@ * * @ingroup MSL_MX53 */ +extern int __init mx53_evk_init_mc13892(void); extern void __init mx53_evk_io_init(void); extern struct cpu_wp *(*get_cpu_wp)(int *wp); extern void (*set_num_cpu_wp)(int num); @@ -84,7 +86,7 @@ static struct cpu_wp cpu_wp_auto[] = { .mfd = 11, .mfn = 5, .cpu_podf = 0, - .cpu_voltage = 1175000,}, + .cpu_voltage = 1150000,}, { .pll_rate = 800000000, .cpu_rate = 800000000, @@ -93,10 +95,10 @@ static struct cpu_wp cpu_wp_auto[] = { .mfd = 2, .mfn = 1, .cpu_podf = 0, - .cpu_voltage = 1100000,}, + .cpu_voltage = 1050000,}, { .pll_rate = 800000000, - .cpu_rate = 166250000, + .cpu_rate = 160000000, .pdf = 4, .mfi = 8, .mfd = 2, @@ -107,7 +109,24 @@ static struct cpu_wp cpu_wp_auto[] = { static struct fb_videomode video_modes[] = { { - /* 720p60 TV output */ + /* NTSC TV output */ + "TV-NTSC", 60, 720, 480, 74074, + 122, 15, + 18, 26, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED, + 0,}, + { + /* PAL TV output */ + "TV-PAL", 50, 720, 576, 74074, + 132, 11, + 22, 26, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST, + 0,}, + { "720P60", 60, 1280, 720, 13468, 260, 109, 25, 4, @@ -117,12 +136,35 @@ static struct fb_videomode video_modes[] = { FB_VMODE_NONINTERLACED, 0,}, { - /* MITSUBISHI LVDS panel */ + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */ + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10, + FB_SYNC_CLK_LAT_FALL, + FB_VMODE_NONINTERLACED, + 0,}, + { + /* 1600x1200 @ 60 Hz 162M pixel clk*/ + "UXGA", 60, 1600, 1200, 6172, + 304, 64, + 1, 46, + 192, 3, + FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT | + FB_SYNC_EXT, + FB_VMODE_NONINTERLACED, + 0,}, + { + "1080P60", 60, 1920, 1080, 7692, + 100, 40, + 30, 3, + 10, 2, + FB_SYNC_EXT, + FB_VMODE_NONINTERLACED, + 0,}, + { "XGA", 60, 1024, 768, 15385, 220, 40, 21, 7, 60, 10, - 0, + FB_SYNC_EXT, FB_VMODE_NONINTERLACED, 0,}, }; @@ -150,6 +192,43 @@ static struct platform_pwm_backlight_data mxc_pwm_backlight_data = { .pwm_period_ns = 78770, }; +extern void flexcan_xcvr_enable(int id, int en); + +static struct flexcan_platform_data flexcan0_data = { + .core_reg = NULL, + .io_reg = NULL, + .xcvr_enable = flexcan_xcvr_enable, + .br_clksrc = 1, + .br_rjw = 2, + .br_presdiv = 5, + .br_propseg = 5, + .br_pseg1 = 4, + .br_pseg2 = 7, + .bcc = 1, + .srx_dis = 1, + .smp = 1, + .boff_rec = 1, + .ext_msg = 1, + .std_msg = 1, +}; +static struct flexcan_platform_data flexcan1_data = { + .core_reg = NULL, + .io_reg = NULL, + .xcvr_enable = flexcan_xcvr_enable, + .br_clksrc = 1, + .br_rjw = 2, + .br_presdiv = 5, + .br_propseg = 5, + .br_pseg1 = 4, + .br_pseg2 = 7, + .bcc = 1, + .srx_dis = 1, + .boff_rec = 1, + .ext_msg = 1, + .std_msg = 1, +}; + + extern void mx5_ipu_reset(void); static struct mxc_ipu_config mxc_ipu_data = { .rev = 3, @@ -161,6 +240,10 @@ static struct mxc_vpu_platform_data mxc_vpu_data = { .reset = mx5_vpu_reset, }; +static struct fec_platform_data fec_data = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + extern void mx53_evk_gpio_spi_chipselect_active(int cspi_mode, int status, int chipselect); extern void mx53_evk_gpio_spi_chipselect_inactive(int cspi_mode, int status, @@ -180,10 +263,63 @@ static struct mxc_srtc_platform_data srtc_data = { .srtc_sec_mode_addr = 0x83F98840, }; +static struct mxc_dvfs_platform_data dvfs_core_data = { + .reg_id = "SW1", + .clk1_id = "cpu_clk", + .clk2_id = "gpc_dvfs_clk", + .gpc_cntr_reg_addr = MXC_GPC_CNTR, + .gpc_vcr_reg_addr = MXC_GPC_VCR, + .ccm_cdcr_reg_addr = MXC_CCM_CDCR, + .ccm_cacrr_reg_addr = MXC_CCM_CACRR, + .ccm_cdhipr_reg_addr = MXC_CCM_CDHIPR, + .prediv_mask = 0x1F800, + .prediv_offset = 11, + .prediv_val = 3, + .div3ck_mask = 0xE0000000, + .div3ck_offset = 29, + .div3ck_val = 2, + .emac_val = 0x08, + .upthr_val = 25, + .dnthr_val = 9, + .pncthr_val = 33, + .upcnt_val = 10, + .dncnt_val = 10, + .delay_time = 30, + .num_wp = 3, +}; + static struct tve_platform_data tve_data = { .dac_reg = "VVIDEO", }; +static struct ldb_platform_data ldb_data = { + .lvds_bg_reg = "VAUDIO", + .ext_ref = 1, +}; + +static struct mxc_esai_platform_data esai_data = { + .activate_esai_ports = gpio_activate_esai_ports, +}; + +static void adv7180_pwdn(int pwdn) +{ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), "gpio5_23"); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 0); + if (pwdn) + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 0); + else + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 1); +} + +static struct mxc_tvin_platform_data adv7180_data = { + .dvddio_reg = NULL, + .dvdd_reg = NULL, + .avdd_reg = NULL, + .pvdd_reg = NULL, + .pwdn = adv7180_pwdn, + .reset = NULL, +}; + static struct resource mxcfb_resources[] = { [0] = { .flags = IORESOURCE_MEM, @@ -193,101 +329,43 @@ static struct resource mxcfb_resources[] = { static struct mxc_fb_platform_data fb_data[] = { { .interface_pix_fmt = IPU_PIX_FMT_RGB565, - .mode_str = "800x480M-16@55", + .mode_str = "CLAA-WVGA", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), }, { - .interface_pix_fmt = IPU_PIX_FMT_RGB24, + .interface_pix_fmt = IPU_PIX_FMT_BGR24, .mode_str = "1024x768M-16@60", + .mode = video_modes, + .num_modes = ARRAY_SIZE(video_modes), }, }; -static int __initdata enable_vga = { 0 }; -static int __initdata enable_tv = { 0 }; -static int __initdata enable_dvi = { 0 }; - -static void wvga_reset(void) -{ -} - -static struct mxc_lcd_platform_data lcd_wvga_data = { - .reset = wvga_reset, -}; - -static struct platform_device lcd_wvga_device = { - .name = "lcd_claa", -}; - +extern int primary_di; static int __init mxc_init_fb(void) { if (!machine_is_mx53_evk()) return 0; - /* by default, fb0 is wvga, fb1 is vga or tv */ - if (enable_vga) { - printk(KERN_INFO "VGA monitor is primary\n"); - } else if (enable_tv == 2) - printk(KERN_INFO "HDTV is primary\n"); - else if (enable_dvi) - printk(KERN_INFO "DVI is primary\n"); - else - printk(KERN_INFO "WVGA LCD panel is primary\n"); - - if (enable_tv) { - printk(KERN_INFO "HDTV is specified as %d\n", enable_tv); - fb_data[1].interface_pix_fmt = IPU_PIX_FMT_YUV444; - fb_data[1].mode = &(video_modes[0]); - } - - if (enable_dvi) { - fb_data[0].mode_str = "1024x768M-16@60"; - fb_data[0].interface_pix_fmt = IPU_PIX_FMT_RGB24; - } - - /* Once a customer knows the platform configuration, - this should be simplified to what is desired. - */ - if (enable_vga || enable_tv == 2) { - /* - * DI1 -> DP-BG channel: - * - * dev di-out-fmt default-videmode - * - * 1. VGA RGB 1024x768M-16@60 - * 2. TVE YUV video_modes[0] - */ + if (primary_di) { + printk(KERN_INFO "DI1 is primary\n"); + /* DI1 -> DP-BG channel: */ mxc_fb_devices[1].num_resources = ARRAY_SIZE(mxcfb_resources); mxc_fb_devices[1].resource = mxcfb_resources; mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); - if (fb_data[0].mode_str || fb_data[0].mode) - /* - * DI0 -> DC channel: - * - * dev di-out-fmt default-videmode - * - * 1. WVGA RGB 800x480M-16@55 - */ - mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); + + /* DI0 -> DC channel: */ + mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); } else { - /* - * DI0 -> DP-BG channel: - * - * dev di-out-fmt default-videmode - * - * 1. WVGA RGB 800x480M-16@55 - */ + printk(KERN_INFO "DI0 is primary\n"); + + /* DI0 -> DP-BG channel: */ mxc_fb_devices[0].num_resources = ARRAY_SIZE(mxcfb_resources); mxc_fb_devices[0].resource = mxcfb_resources; mxc_register_device(&mxc_fb_devices[0], &fb_data[0]); - if (fb_data[1].mode_str || fb_data[1].mode) - /* - * DI1 -> DC channel: - * - * dev di-out-fmt default-videmode - * - * 1. VGA RGB 1024x768M-16@60 - * 2. TVE YUV video_modes[0] - */ - mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); + + /* DI1 -> DC channel: */ + mxc_register_device(&mxc_fb_devices[1], &fb_data[1]); } /* @@ -299,33 +377,18 @@ static int __init mxc_init_fb(void) } device_initcall(mxc_init_fb); -static int __init dvi_setup(char *s) -{ - enable_dvi = 1; - return 1; -} -__setup("dvi", dvi_setup); - -static int __init vga_setup(char *__unused) +static void camera_pwdn(int pwdn) { - enable_vga = 1; - return 1; + gpio_request(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), "gpio5_23"); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), pwdn); } -__setup("vga", vga_setup); - -static int __init tv_setup(char *s) -{ - enable_tv = 1; - if (strcmp(s, "2") == 0 || strcmp(s, "=2") == 0) - enable_tv = 2; - return 1; -} -__setup("hdtv", tv_setup); static struct mxc_camera_platform_data camera_data = { .analog_regulator = "VSD", .mclk = 24000000, .csi = 0, + .pwdn = camera_pwdn, }; static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { @@ -334,6 +397,15 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { .addr = 0x3C, .platform_data = (void *)&camera_data, }, + { + .type = "adv7180", + .addr = 0x21, + .platform_data = (void *)&adv7180_data, + }, + { + .type = "cs42888", + .addr = 0x48, + }, }; /* TO DO add platform data */ @@ -361,6 +433,35 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { }, }; +static struct mtd_partition mxc_dataflash_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x000100000,}, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL,}, +}; + +static struct flash_platform_data mxc_spi_flash_data[] = { + { + .name = "mxc_dataflash", + .parts = mxc_dataflash_partitions, + .nr_parts = ARRAY_SIZE(mxc_dataflash_partitions), + .type = "at45db321d",} +}; + + +static struct spi_board_info mxc_dataflash_device[] __initdata = { + { + .modalias = "mxc_dataflash", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .platform_data = &mxc_spi_flash_data[0],}, +}; + static int sdhc_write_protect(struct device *dev) { unsigned short rc = 0; @@ -410,7 +511,8 @@ static struct mxc_mmc_platform_data mmc1_data = { static struct mxc_mmc_platform_data mmc3_data = { .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_31_32, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA + | MMC_CAP_DATA_DDR, .min_clk = 400000, .max_clk = 50000000, .card_inserted_state = 0, @@ -419,6 +521,161 @@ static struct mxc_mmc_platform_data mmc3_data = { .clock_mmc = "esdhc_clk", }; +/* return value 1 failure, 0 success */ +static int write_phy_ctl_ack_polling(u32 data, void __iomem *mmio, + int max_iterations, u32 exp_val) +{ + enum { + PORT_PHY_CTL = 0x178, /* Port0 PHY Control */ + PORT_PHY_SR = 0x17c, /* Port0 PHY Status */ + /* PORT_PHY_SR */ + PORT_PHY_STAT_DATA_LOC = 0, + PORT_PHY_STAT_ACK_LOC = 18, + }; + int i; + u32 val; + + writel(data, mmio + PORT_PHY_CTL); + + for (i = 0; i < max_iterations + 1; i++) { + val = readl(mmio + PORT_PHY_SR); + val = (val >> PORT_PHY_STAT_ACK_LOC) & 0x1; + if (val == exp_val) + return 0; + if (i == max_iterations) { + printk(KERN_ERR "Wait for CR ACK error!\n"); + return 1; + } + msleep(1); + } + return 0; +} + +/* HW Initialization, if return 1, initialization is failed. */ +static int sata_init(struct device *dev) +{ + enum { + HOST_CAP = 0x00, + HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ + HOST_PORTS_IMPL = 0x0c, + HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ + /* Offest used to control the MPLL input clk */ + PHY_CR_CLOCK_FREQ_OVRD = 0x12, + + PORT_PHY_CTL = 0x178, /* Port0 PHY Control */ + /* PORT_PHY_CTL bits */ + PORT_PHY_CTL_CAP_ADR_LOC = 0x10000, + PORT_PHY_CTL_CAP_DAT_LOC = 0x20000, + PORT_PHY_CTL_WRITE_LOC = 0x40000, + }; + void __iomem *mmio; + struct clk *clk; + int rc = 0; + u32 tmpdata; + + clk = clk_get(dev, "sata_clk"); + clk_enable(clk); + + mmio = ioremap(MX53_SATA_BASE_ADDR, SZ_4K); + + tmpdata = readl(mmio + HOST_CAP); + if (!(tmpdata & HOST_CAP_SSS)) { + tmpdata |= HOST_CAP_SSS; + writel(tmpdata, mmio + HOST_CAP); + } + + if (!(readl(mmio + HOST_PORTS_IMPL) & 0x1)) + writel((readl(mmio + HOST_PORTS_IMPL) | 0x1), + mmio + HOST_PORTS_IMPL); + + /* Get the AHB clock rate, and configure the TIMER1MS reg */ + clk = clk_get(NULL, "ahb_clk"); + tmpdata = clk_get_rate(clk) / 1000; + writel(tmpdata, mmio + HOST_TIMER1MS); + + /* write addr */ + tmpdata = PHY_CR_CLOCK_FREQ_OVRD; + writel(tmpdata, mmio + PORT_PHY_CTL); + /* capture addr */ + tmpdata |= PORT_PHY_CTL_CAP_ADR_LOC; + /* Wait for ack */ + if (write_phy_ctl_ack_polling(tmpdata, mmio, 100, 1)) { + rc = 1; + goto err0; + } + + /* deassert cap data */ + tmpdata &= 0xFFFF; + /* wait for ack de-assertion */ + if (write_phy_ctl_ack_polling(tmpdata, mmio, 100, 0)) { + rc = 1; + goto err0; + } + + /* write data */ + /* Configure the PHY CLK input refer to different OSC + * For 25MHz, pre[13,14]:01, ncy[12,8]:06, + * ncy5[7,6]:02, int_ctl[5,3]:0, prop_ctl[2,0]:7. + * For 50MHz, pre:00, ncy:06, ncy5:02, int_ctl:0, prop_ctl:7. + */ + /* EVK revA */ + if (board_is_mx53_evk_a()) + tmpdata = (0x1 << 15) | (0x1 << 13) | (0x6 << 8) + | (0x2 << 6) | 0x7; + /* EVK revB */ + else if (board_is_mx53_evk_b()) + tmpdata = (0x1 << 15) | (0x0 << 13) | (0x6 << 8) + | (0x2 << 6) | 0x7; + + writel(tmpdata, mmio + PORT_PHY_CTL); + /* capture data */ + tmpdata |= PORT_PHY_CTL_CAP_DAT_LOC; + /* wait for ack */ + if (write_phy_ctl_ack_polling(tmpdata, mmio, 100, 1)) { + rc = 1; + goto err0; + } + + /* deassert cap data */ + tmpdata &= 0xFFFF; + /* wait for ack de-assertion */ + if (write_phy_ctl_ack_polling(tmpdata, mmio, 100, 0)) { + rc = 1; + goto err0; + } + + /* assert wr signal and wait for ack */ + if (write_phy_ctl_ack_polling(PORT_PHY_CTL_WRITE_LOC, mmio, 100, 1)) { + rc = 1; + goto err0; + } + /* deassert rd _signal and wait for ack de-assertion */ + if (write_phy_ctl_ack_polling(0, mmio, 100, 0)) { + rc = 1; + goto err0; + } + + msleep(10); + +err0: + iounmap(mmio); + return rc; +} + +static void sata_exit(struct device *dev) +{ + struct clk *clk; + + clk = clk_get(dev, "sata_clk"); + clk_disable(clk); + clk_put(clk); +} + +static struct ahci_platform_data sata_data = { + .init = sata_init, + .exit = sata_exit, +}; + static int mxc_sgtl5000_amp_enable(int enable) { /* TO DO */ @@ -474,6 +731,102 @@ static struct platform_device mxc_sgtl5000_device = { .name = "imx-3stack-sgtl5000", }; +static struct mxc_mlb_platform_data mlb_data = { + .reg_nvcc = "VCAM", + .mlb_clk = "mlb_clk", +}; + +/* NAND Flash Partitions */ +#ifdef CONFIG_MTD_PARTITIONS +static struct mtd_partition nand_flash_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 3 * 1024 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 5 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024 * 1024}, + { + .name = "nand.userfs1", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024 * 1024}, + { + .name = "nand.userfs2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; +#endif + +static int nand_init(void) +{ + u32 i, reg; + void __iomem *base; + + #define M4IF_GENP_WEIM_MM_MASK 0x00000001 + #define WEIM_GCR2_MUX16_BYP_GRANT_MASK 0x00001000 + + base = ioremap(MX53_BASE_ADDR(M4IF_BASE_ADDR), SZ_4K); + reg = __raw_readl(base + 0xc); + reg &= ~M4IF_GENP_WEIM_MM_MASK; + __raw_writel(reg, base + 0xc); + + iounmap(base); + + base = ioremap(MX53_BASE_ADDR(WEIM_BASE_ADDR), SZ_4K); + for (i = 0x4; i < 0x94; i += 0x18) { + reg = __raw_readl((u32)base + i); + reg &= ~WEIM_GCR2_MUX16_BYP_GRANT_MASK; + __raw_writel(reg, (u32)base + i); + } + + iounmap(base); + + return 0; +} + +static struct flash_platform_data mxc_nand_data = { +#ifdef CONFIG_MTD_PARTITIONS + .parts = nand_flash_partitions, + .nr_parts = ARRAY_SIZE(nand_flash_partitions), +#endif + .width = 1, + .init = nand_init, +}; + +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* Souce from CKIH1 for 44.1K */ + .spdif_clk_48000 = 7, /* Source from CKIH2 for 48k and 32k */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + +static struct mxc_audio_platform_data mxc_surround_audio_data = { + .ext_ram = 1, +}; + + +static struct platform_device mxc_alsa_surround_device = { + .name = "imx-3stack-cs42888", +}; + +static int __initdata mxc_apc_on = { 0 }; /* OFF: 0 (default), ON: 1 */ + +static int __init apc_setup(char *__unused) +{ + mxc_apc_on = 1; + printk(KERN_INFO "Automotive Port Card is Plugged on\n"); + return 1; +} +__setup("apc", apc_setup); + + /*! * Board specific fixup function. It is called by \b setup_arch() in * setup.c file very early on during kernel starts. It allows the user to @@ -558,7 +911,8 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, #endif } } - +extern void mx53_gpio_usbotg_driver_vbus(bool on); +extern void mx53_gpio_host1_driver_vbus(bool on); /*! * Board specific initialization. */ @@ -566,6 +920,8 @@ static void __init mxc_board_init(void) { mxc_ipu_data.di_clk[0] = clk_get(NULL, "ipu_di0_clk"); mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di1_clk"); + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); /* SD card detect irqs */ if (board_is_mx53_arm2()) { @@ -596,7 +952,7 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_rtc_device, &srtc_data); mxc_register_device(&mxc_w1_master_device, &mxc_w1_data); mxc_register_device(&mxc_ipu_device, &mxc_ipu_data); - mxc_register_device(&lcd_wvga_device, &lcd_wvga_data); + mxc_register_device(&mxc_ldb_device, &ldb_data); mxc_register_device(&mxc_tve_device, &tve_data); mxc_register_device(&mxcvpu_device, &mxc_vpu_data); mxc_register_device(&gpu_device, NULL); @@ -605,29 +961,34 @@ static void __init mxc_board_init(void) mxc_register_device(&mx53_lpmode_device, NULL); mxc_register_device(&busfreq_device, NULL); mxc_register_device(&sdram_autogating_device, NULL); + */ mxc_register_device(&mxc_dvfs_core_device, &dvfs_core_data); + mxc_register_device(&busfreq_device, NULL); + + /* mxc_register_device(&mxc_dvfs_per_device, &dvfs_per_data); */ + mxc_register_device(&mxc_iim_device, NULL); if (!board_is_mx53_arm2()) { mxc_register_device(&mxc_pwm2_device, NULL); mxc_register_device(&mxc_pwm_backlight_device, &mxc_pwm_backlight_data); } + mxc_register_device(&mxc_flexcan0_device, &flexcan0_data); + mxc_register_device(&mxc_flexcan1_device, &flexcan1_data); + /* mxc_register_device(&mxc_keypad_device, &keypad_plat_data); */ mxc_register_device(&mxcsdhc1_device, &mmc1_data); mxc_register_device(&mxcsdhc3_device, &mmc3_data); mxc_register_device(&mxc_ssi1_device, NULL); mxc_register_device(&mxc_ssi2_device, NULL); - /* + mxc_register_device(&ahci_fsl_device, &sata_data); mxc_register_device(&mxc_alsa_spdif_device, &mxc_spdif_data); - */ - mxc_register_device(&mxc_fec_device, NULL); -/* - spi_register_board_info(mxc_spi_nor_device, - ARRAY_SIZE(mxc_spi_nor_device)); -*/ - + if (!mxc_apc_on) + mxc_register_device(&mxc_fec_device, &fec_data); + spi_register_board_info(mxc_dataflash_device, + ARRAY_SIZE(mxc_dataflash_device)); i2c_register_board_info(0, mxc_i2c0_board_info, ARRAY_SIZE(mxc_i2c0_board_info)); i2c_register_board_info(1, mxc_i2c1_board_info, @@ -638,8 +999,17 @@ static void __init mxc_board_init(void) pm_power_off = mxc_power_off; */ mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data); + mxc_register_device(&mxc_mlb_device, &mlb_data); + mx5_set_otghost_vbus_func(mx53_gpio_usbotg_driver_vbus); mx5_usb_dr_init(); + mx5_set_host1_vbus_func(mx53_gpio_host1_driver_vbus); mx5_usbh1_init(); + mxc_register_device(&mxc_nandv2_mtd_device, &mxc_nand_data); + if (mxc_apc_on) { + mxc_register_device(&mxc_esai_device, &esai_data); + mxc_register_device(&mxc_alsa_surround_device, + &mxc_surround_audio_data); + } } static void __init mx53_evk_timer_init(void) diff --git a/arch/arm/mach-mx5/mx53_evk_gpio.c b/arch/arm/mach-mx5/mx53_evk_gpio.c index 450280e2d96a..caeee73ea414 100644 --- a/arch/arm/mach-mx5/mx53_evk_gpio.c +++ b/arch/arm/mach-mx5/mx53_evk_gpio.c @@ -50,15 +50,21 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { }, { MX53_PIN_EIM_D16, IOMUX_CONFIG_ALT4, + PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_HIGH, + MUX_IN_ECSPI1_IPP_CSPI_CLK_IN_SELECT_INPUT, + INPUT_CTL_PATH3, }, { MX53_PIN_EIM_D17, IOMUX_CONFIG_ALT4, + PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_HIGH, + MUX_IN_ECSPI1_IPP_IND_MISO_SELECT_INPUT, + INPUT_CTL_PATH3, }, { - MX53_PIN_EIM_D18, IOMUX_CONFIG_ALT2, - }, - { - MX53_PIN_EIM_D19, IOMUX_CONFIG_ALT2, + MX53_PIN_EIM_D18, IOMUX_CONFIG_ALT4, + PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_HIGH, + MUX_IN_ECSPI1_IPP_IND_MOSI_SELECT_INPUT, + INPUT_CTL_PATH3, }, { MX53_PIN_EIM_D20, IOMUX_CONFIG_ALT3, @@ -73,9 +79,6 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { MX53_PIN_EIM_D26, IOMUX_CONFIG_GPIO, }, { - MX53_PIN_EIM_D28, IOMUX_CONFIG_ALT3, - }, - { MX53_PIN_EIM_D29, IOMUX_CONFIG_ALT3, }, { @@ -85,12 +88,6 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { MX53_PIN_EIM_D31, IOMUX_CONFIG_ALT4, }, { - MX53_PIN_NANDF_CS2, IOMUX_CONFIG_ALT3, - }, - { - MX53_PIN_NANDF_CS3, IOMUX_CONFIG_ALT3, - }, - { MX53_PIN_ATA_BUFFER_EN, IOMUX_CONFIG_ALT3, (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), @@ -166,31 +163,7 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { MX53_PIN_KEY_ROW1, IOMUX_CONFIG_ALT2, }, { - MX53_PIN_KEY_COL2, IOMUX_CONFIG_ALT2, - }, - { - MX53_PIN_KEY_ROW2, IOMUX_CONFIG_ALT2, - }, - { - MX53_PIN_KEY_COL3, IOMUX_CONFIG_ALT4, - }, - { - MX53_PIN_KEY_COL4, IOMUX_CONFIG_ALT2, - }, - { - MX53_PIN_KEY_ROW4, IOMUX_CONFIG_ALT2, - }, - { - MX53_PIN_CSI0_D4, IOMUX_CONFIG_ALT5, - }, - { - MX53_PIN_CSI0_D6, IOMUX_CONFIG_ALT5, - }, - { - MX53_PIN_CSI0_D7, IOMUX_CONFIG_ALT5, - }, - { - MX53_PIN_CSI0_D9, IOMUX_CONFIG_ALT5, + MX53_PIN_CSI0_D7, IOMUX_CONFIG_ALT1, }, { /* UART1 Tx */ MX53_PIN_CSI0_D10, IOMUX_CONFIG_ALT2, @@ -205,19 +178,31 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { INPUT_CTL_PATH1, }, { - MX53_PIN_GPIO_2, IOMUX_CONFIG_GPIO, + MX53_PIN_GPIO_2, IOMUX_CONFIG_ALT7, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | + PAD_CTL_360K_PD), + MUX_IN_MLB_MLBDAT_IN_SELECT_INPUT, + INPUT_CTL_PATH2, }, { - MX53_PIN_GPIO_3, IOMUX_CONFIG_GPIO, + MX53_PIN_GPIO_3, IOMUX_CONFIG_ALT7, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | + PAD_CTL_360K_PD), + MUX_IN_MLB_MLBCLK_IN_SELECT_INPUT, + INPUT_CTL_PATH2, }, { MX53_PIN_GPIO_4, IOMUX_CONFIG_GPIO, }, { - MX53_PIN_GPIO_5, IOMUX_CONFIG_GPIO, - }, - { - MX53_PIN_GPIO_6, IOMUX_CONFIG_GPIO, + MX53_PIN_GPIO_6, IOMUX_CONFIG_ALT7, + (PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | + PAD_CTL_360K_PD), + MUX_IN_MLB_MLBSIG_IN_SELECT_INPUT, + INPUT_CTL_PATH2, }, { MX53_PIN_GPIO_7, IOMUX_CONFIG_GPIO, @@ -228,29 +213,79 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { { MX53_PIN_GPIO_10, IOMUX_CONFIG_GPIO, }, - { - MX53_PIN_GPIO_11, IOMUX_CONFIG_GPIO, + { /* CAN1-TX */ + MX53_PIN_KEY_COL2, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE), }, - { - MX53_PIN_GPIO_12, IOMUX_CONFIG_GPIO, + { /* CAN1-RX */ + MX53_PIN_KEY_ROW2, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_360K_PD | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_CAN1_IPP_IND_CANRX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* CAN1 -- EN */ + MX53_PIN_GPIO_18, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_360K_PD | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { /* CAN1 -- STBY */ + MX53_PIN_GPIO_17, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_360K_PD | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { /* CAN1 -- NERR */ + MX53_PIN_GPIO_5, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_360K_PD | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_CAN2_IPP_IND_CANRX_SELECT_INPUT, + INPUT_CTL_PATH1, }, - { - MX53_PIN_GPIO_13, IOMUX_CONFIG_GPIO, + { /* CAN2-TX */ + MX53_PIN_KEY_COL4, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE), }, - { - MX53_PIN_GPIO_14, IOMUX_CONFIG_GPIO, + { /* CAN2-RX */ + MX53_PIN_KEY_ROW4, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_360K_PD | PAD_CTL_ODE_OPENDRAIN_NONE), + MUX_IN_CAN2_IPP_IND_CANRX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* CAN2 -- EN */ + MX53_PIN_CSI0_D6, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { /* CAN2 -- STBY */ + MX53_PIN_GPIO_14, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE), + }, + { /* CAN2 -- NERR */ + MX53_PIN_CSI0_D4, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE), }, { - MX53_PIN_GPIO_16, IOMUX_CONFIG_ALT1, + MX53_PIN_GPIO_11, IOMUX_CONFIG_GPIO, + }, + { /* ESAI reset */ + MX53_PIN_GPIO_12, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_SRE_FAST), }, { - MX53_PIN_GPIO_17, IOMUX_CONFIG_GPIO, + MX53_PIN_GPIO_13, IOMUX_CONFIG_GPIO, }, { - MX53_PIN_GPIO_18, IOMUX_CONFIG_GPIO, + MX53_PIN_GPIO_16, IOMUX_CONFIG_ALT1, }, { - MX53_PIN_GPIO_19, IOMUX_CONFIG_ALT3, + MX53_PIN_GPIO_19, IOMUX_CONFIG_ALT1, }, { /* DI0 display clock */ MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0, @@ -392,6 +427,36 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { (PAD_CTL_HYS_NONE | PAD_CTL_PKE_NONE | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_DRV_HIGH | PAD_CTL_SRE_SLOW), }, + { + MX53_PIN_LVDS0_TX3_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS0_CLK_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS0_TX2_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS0_TX1_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS0_TX0_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS1_TX3_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS1_CLK_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS1_TX2_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS1_TX1_P, IOMUX_CONFIG_ALT1, + }, + { + MX53_PIN_LVDS1_TX0_P, IOMUX_CONFIG_ALT1, + }, { /* audio and CSI clock out */ MX53_PIN_GPIO_0, IOMUX_CONFIG_ALT3, }, @@ -450,68 +515,100 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { /* esdhc1 */ { MX53_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_SD1_DATA0, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_SD1_DATA1, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_SD1_DATA2, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_SD1_DATA3, IOMUX_CONFIG_ALT0, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, /* esdhc3 */ { MX53_PIN_ATA_DATA0, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA1, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA2, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA3, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA8, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA9, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA10, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_DATA11, IOMUX_CONFIG_ALT4, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_IORDY, IOMUX_CONFIG_ALT2, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { MX53_PIN_ATA_RESET_B, IOMUX_CONFIG_ALT2, - (PAD_CTL_DRV_HIGH | PAD_CTL_75k_PU | PAD_CTL_SRE_FAST), + (PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH + | PAD_CTL_22K_PU | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE + | PAD_CTL_SRE_FAST), }, { /* FEC pins */ MX53_PIN_FEC_MDIO, IOMUX_CONFIG_ALT0, @@ -556,6 +653,38 @@ static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { MX53_PIN_FEC_MDC, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, }, + { /* I2C1 SDA */ + MX53_PIN_CSI0_D8, IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + MUX_IN_I2C1_IPP_SDA_IN_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* I2C1 SCL */ + MX53_PIN_CSI0_D9, IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + MUX_IN_I2C1_IPP_SCL_IN_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* I2C2 SDA */ + MX53_PIN_KEY_ROW3, IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* I2C1 SCL */ + MX53_PIN_KEY_COL3, IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, + INPUT_CTL_PATH0, + }, }; static struct mxc_iomux_pin_cfg __initdata mx53_evk_iomux_pins[] = { @@ -631,11 +760,87 @@ static int __initdata enable_w1 = { 0 }; static int __init w1_setup(char *__unused) { enable_w1 = 1; - return 1; + return cpu_is_mx53(); } __setup("w1", w1_setup); +static struct mxc_iomux_pin_cfg __initdata nand_iomux_pins[] = { + { + MX53_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_RB0, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU, + }, + { + MX53_PIN_NANDF_CLE, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_ALE, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU, + }, + { + MX53_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT0, PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA0, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA1, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA2, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA3, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA4, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA5, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA6, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, + { + MX53_PIN_EIM_DA7, IOMUX_CONFIG_ALT0, + PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH, + }, +}; + +static int __initdata enable_spdif = { 0 }; +static int __init spdif_setup(char *__unused) +{ + enable_spdif = 1; + return 1; +} + +__setup("spdif", spdif_setup); + void __init mx53_evk_io_init(void) { int i; @@ -665,12 +870,12 @@ void __init mx53_evk_io_init(void) mx53_arm2_iomux_pins[i].in_mode); } - /* Enable OTG VBus with GPIO low */ + /* Config GPIO for OTG VBus */ mxc_iomux_set_pad(MX53_PIN_EIM_D22, PAD_CTL_DRV_HIGH | PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), "gpio3_22"); gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), 0); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), 1); gpio_request(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), "gpio1_1"); gpio_direction_input(IOMUX_TO_GPIO(MX53_PIN_GPIO_1)); /* SD1 CD */ @@ -696,6 +901,9 @@ void __init mx53_evk_io_init(void) PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); gpio_request(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_2), "gpio7_8"); gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_2), 1); + /* shutdown the Host1 Vbus when system bring up, + * Vbus will be opened in Host1 driver's probe function */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_2), 0); /* USB HUB RESET - De-assert USB HUB RESET_N */ mxc_iomux_set_pad(MX53_PIN_CSI0_DATA_EN, PAD_CTL_DRV_HIGH | @@ -708,12 +916,16 @@ void __init mx53_evk_io_init(void) msleep(1); gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_DATA_EN), 1); - /* Enable OTG VBus with GPIO low */ + /* Config GPIO for OTG VBus */ mxc_iomux_set_pad(MX53_PIN_EIM_A23, PAD_CTL_DRV_HIGH | PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), "gpio6_6"); gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 0); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 0); + + if (board_is_mx53_evk_a()) /*rev A,"1" disable, "0" enable vbus*/ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 1); + else if (board_is_mx53_evk_b()) /* rev B,"0" disable,"1" enable Vbus*/ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 0); gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_DA13), "gpio3_13"); gpio_direction_input(IOMUX_TO_GPIO(MX53_PIN_EIM_DA13)); /* SD1 CD */ @@ -735,70 +947,42 @@ void __init mx53_evk_io_init(void) msleep(1); gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_0), 1); - /* DVI Detect */ - gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D31), "gpio3_31"); - gpio_direction_input(IOMUX_TO_GPIO(MX53_PIN_EIM_D31)); - /* DVI Reset - Assert for i2c disabled mode */ - gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), "gpio5_0"); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), 0); - gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), 0); - /* DVI Power-down */ - gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), "gpio3_24"); - gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), 0); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), 1); - /* DVI I2C enable */ - gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), "gpio3_28"); - gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), 0); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), 0); + /* CS42888 reset GPIO */ + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_12), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_12), 0); + } + /* DVI Detect */ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D31), "gpio3_31"); + gpio_direction_input(IOMUX_TO_GPIO(MX53_PIN_EIM_D31)); + /* DVI Reset - Assert for i2c disabled mode */ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), "gpio5_0"); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), 0); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_WAIT), 0); + /* DVI Power-down */ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), "gpio3_24"); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D24), 1); + /* DVI I2C enable */ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), "gpio3_28"); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D28), 0); + + for (i = 0; i < ARRAY_SIZE(nand_iomux_pins); i++) { + mxc_request_iomux(nand_iomux_pins[i].pin, + nand_iomux_pins[i].mux_mode); + if (nand_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(nand_iomux_pins[i].pin, + nand_iomux_pins[i].pad_cfg); + if (nand_iomux_pins[i].in_select) + mxc_iomux_set_input(nand_iomux_pins[i].in_select, + nand_iomux_pins[i].in_mode); + } gpio_request(IOMUX_TO_GPIO(MX53_PIN_GPIO_16), "gpio7_11"); gpio_direction_input(IOMUX_TO_GPIO(MX53_PIN_GPIO_16)); /*PMIC_INT*/ - - /* i2c1 SDA */ - mxc_request_iomux(MX53_PIN_CSI0_D8, - IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION); - mxc_iomux_set_input(MUX_IN_I2C1_IPP_SDA_IN_SELECT_INPUT, - INPUT_CTL_PATH0); - mxc_iomux_set_pad(MX53_PIN_CSI0_D8, PAD_CTL_SRE_FAST | - PAD_CTL_ODE_OPENDRAIN_ENABLE | - PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | - PAD_CTL_HYS_ENABLE); - - /* i2c1 SCL */ - mxc_request_iomux(MX53_PIN_CSI0_D9, - IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION); - mxc_iomux_set_input(MUX_IN_I2C1_IPP_SCL_IN_SELECT_INPUT, - INPUT_CTL_PATH0); - mxc_iomux_set_pad(MX53_PIN_CSI0_D9, PAD_CTL_SRE_FAST | - PAD_CTL_ODE_OPENDRAIN_ENABLE | - PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | - PAD_CTL_HYS_ENABLE); - - /* i2c2 SDA */ - mxc_request_iomux(MX53_PIN_KEY_ROW3, - IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); - mxc_iomux_set_input(MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, - INPUT_CTL_PATH0); - mxc_iomux_set_pad(MX53_PIN_KEY_ROW3, - PAD_CTL_SRE_FAST | - PAD_CTL_ODE_OPENDRAIN_ENABLE | - PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | - PAD_CTL_HYS_ENABLE); - - /* i2c2 SCL */ - mxc_request_iomux(MX53_PIN_KEY_COL3, - IOMUX_CONFIG_ALT4 | IOMUX_CONFIG_SION); - mxc_iomux_set_input(MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, - INPUT_CTL_PATH0); - mxc_iomux_set_pad(MX53_PIN_KEY_COL3, - PAD_CTL_SRE_FAST | - PAD_CTL_ODE_OPENDRAIN_ENABLE | - PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | - PAD_CTL_HYS_ENABLE); - /* headphone_det_b */ mxc_request_iomux(MX53_PIN_ATA_DATA5, IOMUX_CONFIG_GPIO); mxc_iomux_set_pad(MX53_PIN_ATA_DATA5, PAD_CTL_100K_PU); @@ -814,36 +998,82 @@ void __init mx53_evk_io_init(void) gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_10), 0); gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_10), 1); - /* Camera low power */ - gpio_request(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), "gpio5_23"); - gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 0); - gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D5), 0); + /* TVIN reset */ + gpio_request(IOMUX_TO_GPIO(MX53_PIN_CSI0_D7), "gpio5_25"); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_CSI0_D7), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D7), 0); + msleep(5); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D7), 1); + + /* CAN1 enable GPIO*/ + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_18), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_18), 0); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_17), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_17), 0); + + /* CAN2 enable GPIO*/ + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_CSI0_D6), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D6), 0); + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_14), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_14), 0); + + if (enable_spdif) { + mxc_free_iomux(MX53_PIN_GPIO_19, IOMUX_CONFIG_ALT1); + mxc_request_iomux(MX53_PIN_GPIO_19, IOMUX_CONFIG_ALT3); + mxc_iomux_set_pad(MX53_PIN_GPIO_19, + PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | + PAD_CTL_PUE_PULL | PAD_CTL_100K_PU | + PAD_CTL_PKE_ENABLE); + } else { + /* GPIO for CAN 12V */ + gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_19), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_19), 0); + } } /* workaround for ecspi chipselect pin may not keep correct level when idle */ void mx53_evk_gpio_spi_chipselect_active(int cspi_mode, int status, int chipselect) { - u32 gpio; - switch (cspi_mode) { case 1: switch (chipselect) { case 0x1: - mxc_request_iomux(MX53_PIN_EIM_D19, - IOMUX_CONFIG_ALT4); + /* de-select SS1 of instance: ecspi1. */ + mxc_request_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_ALT1); mxc_iomux_set_pad(MX53_PIN_EIM_D19, PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | - PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + PAD_CTL_PUE_PULL | + PAD_CTL_100K_PU | + PAD_CTL_DRV_HIGH); + + /* mux mode: ALT4 mux port: SS0 of instance: ecspi1. */ + mxc_request_iomux(MX53_PIN_EIM_EB2, IOMUX_CONFIG_ALT4); + mxc_iomux_set_pad(MX53_PIN_EIM_EB2, + PAD_CTL_HYS_ENABLE | + PAD_CTL_DRV_HIGH); + mxc_iomux_set_input( + MUX_IN_ECSPI1_IPP_IND_SS_B_1_SELECT_INPUT, + INPUT_CTL_PATH3); break; case 0x2: - gpio = IOMUX_TO_GPIO(MX53_PIN_EIM_D19); - mxc_request_iomux(MX53_PIN_EIM_D19, - IOMUX_CONFIG_GPIO); - gpio_request(gpio, "cspi1_ss1"); - gpio_direction_output(gpio, 0); - gpio_set_value(gpio, 1 & (~status)); + /* de-select SS0 of instance: ecspi1. */ + mxc_request_iomux(MX53_PIN_EIM_EB2, IOMUX_CONFIG_ALT1); + mxc_iomux_set_pad(MX53_PIN_EIM_EB2, + PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL | + PAD_CTL_100K_PU | + PAD_CTL_DRV_HIGH); + mxc_request_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_ALT4); + mxc_iomux_set_pad(MX53_PIN_EIM_D19, + PAD_CTL_HYS_ENABLE | + PAD_CTL_DRV_HIGH); + mxc_iomux_set_input( + MUX_IN_ECSPI1_IPP_IND_SS_B_1_SELECT_INPUT, + INPUT_CTL_PATH3); + break; default: break; @@ -870,9 +1100,14 @@ void mx53_evk_gpio_spi_chipselect_inactive(int cspi_mode, int status, mxc_request_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_GPIO); mxc_free_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX53_PIN_EIM_EB2, IOMUX_CONFIG_ALT4); break; case 0x2: - mxc_free_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX53_PIN_EIM_EB2, IOMUX_CONFIG_ALT4); + mxc_request_iomux(MX53_PIN_EIM_EB2, + IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX53_PIN_EIM_EB2, IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX53_PIN_EIM_D19, IOMUX_CONFIG_ALT4); break; default: break; @@ -888,8 +1123,201 @@ void mx53_evk_gpio_spi_chipselect_inactive(int cspi_mode, int status, } EXPORT_SYMBOL(mx53_evk_gpio_spi_chipselect_inactive); +void flexcan_xcvr_enable(int id, int en) +{ + static int pwdn; + if (id < 0 || id > 1) + return; + + if (en) { + if (!(pwdn++)) + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_19), 1); + + if (id == 0) { + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_18), 1); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_17), 1); + } else { + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D6), 1); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_14), 1); + } + + } else { + if (!(--pwdn)) + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_19), 0); + + if (id == 0) { + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_18), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_17), 0); + } else { + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_CSI0_D6), 0); + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_14), 0); + } + } +} +EXPORT_SYMBOL(flexcan_xcvr_enable); + void gpio_lcd_active(void) { /* TO DO */ } EXPORT_SYMBOL(gpio_lcd_active); + +void gpio_activate_esai_ports(void) +{ + unsigned int pad_val; + + /* ESAI1-HCKR */ + mxc_request_iomux(MX53_PIN_FEC_RX_ER, IOMUX_CONFIG_ALT2); + /* ESAI1-SCKR */ + mxc_request_iomux(MX53_PIN_FEC_MDIO, IOMUX_CONFIG_ALT2); + /* ESAI1-FSR */ + mxc_request_iomux(MX53_PIN_FEC_REF_CLK, IOMUX_CONFIG_ALT2); + /* ESAI1-HCKT */ + mxc_request_iomux(MX53_PIN_FEC_RXD0, IOMUX_CONFIG_ALT2); + /* ESAI1-SCKT */ + mxc_request_iomux(MX53_PIN_FEC_CRS_DV, IOMUX_CONFIG_ALT2); + /* ESAI1-FST */ + mxc_request_iomux(MX53_PIN_FEC_RXD1, IOMUX_CONFIG_ALT2); + /* ESAI1-TX5-RX0 */ + mxc_request_iomux(MX53_PIN_FEC_MDC, IOMUX_CONFIG_ALT2); + /* ESAI1-TX4-RX1 */ + mxc_request_iomux(MX53_PIN_FEC_TXD0, IOMUX_CONFIG_ALT2); + /* ESAI1-TX3-RX2 */ + mxc_request_iomux(MX53_PIN_FEC_TX_EN, IOMUX_CONFIG_ALT2); + /* ESAI1-TX2-RX3 */ + mxc_request_iomux(MX53_PIN_FEC_TXD1, IOMUX_CONFIG_ALT2); + /* ESAI1-TX1 */ + mxc_request_iomux(MX53_PIN_NANDF_CS3, IOMUX_CONFIG_ALT3); + /* ESAI1-TX0 */ + mxc_request_iomux(MX53_PIN_NANDF_CS2, IOMUX_CONFIG_ALT3); + + pad_val = PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE; + + /* ESAI1-HCKR */ + mxc_iomux_set_pad(MX53_PIN_FEC_RX_ER, pad_val); + /* ESAI1-SCKR */ + mxc_iomux_set_pad(MX53_PIN_FEC_MDIO, pad_val); + /* ESAI1-FSR */ + mxc_iomux_set_pad(MX53_PIN_FEC_REF_CLK, pad_val); + /* ESAI1-HCKT */ + mxc_iomux_set_pad(MX53_PIN_FEC_RXD0, pad_val); + /* ESAI1-SCKT */ + mxc_iomux_set_pad(MX53_PIN_FEC_CRS_DV, pad_val); + /* ESAI1-FST */ + mxc_iomux_set_pad(MX53_PIN_FEC_RXD1, pad_val); + /* ESAI1-TX5-RX0 */ + mxc_iomux_set_pad(MX53_PIN_FEC_MDC, pad_val); + /* ESAI1-TX4-RX1 */ + mxc_iomux_set_pad(MX53_PIN_FEC_TXD0, pad_val); + /* ESAI1-TX3-RX2 */ + mxc_iomux_set_pad(MX53_PIN_FEC_TX_EN, pad_val); + /* ESAI1-TX2-RX3 */ + mxc_iomux_set_pad(MX53_PIN_FEC_TXD1, pad_val); + /* ESAI1-TX1 */ + mxc_iomux_set_pad(MX53_PIN_NANDF_CS3, pad_val); + /* ESAI1-TX0 */ + mxc_iomux_set_pad(MX53_PIN_NANDF_CS2, pad_val); + + /* ESAI1-HCKR */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_HCKR_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-SCKR */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SCKR_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-FSR */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_FSR_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-HCKT */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_HCKT_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-SCKT */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SCKT_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-FST */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_FST_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX5-RX0 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO5_SDI0_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX4-RX1 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO4_SDI1_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX3-RX2 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO3_SDI2_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX2-RX3 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO2_SDI3_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX1 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO1_SELECT_INPUT, + INPUT_CTL_PATH0); + /* ESAI1-TX0 */ + mxc_iomux_set_input(MUX_IN_ESAI1_IPP_IND_SDO0_SELECT_INPUT, + INPUT_CTL_PATH0); + +} +EXPORT_SYMBOL(gpio_activate_esai_ports); + +void gpio_cs42888_pdwn(int pdwn) +{ + if (pdwn) + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_12), 0); + else + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_12), 1); +} +EXPORT_SYMBOL(gpio_cs42888_pdwn); + +static void gpio_usbotg_vbus_active(void) +{ + if (board_is_mx53_arm2()) { + /* MX53 ARM2 CPU board */ + /* Enable OTG VBus with GPIO low */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), 0); + } else if (board_is_mx53_evk_a()) { + /* MX53 EVK board ver A*/ + /* Enable OTG VBus with GPIO low */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 0); + } else if (board_is_mx53_evk_b()) { + /* MX53 EVK board ver B*/ + /* Enable OTG VBus with GPIO high */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 1); + } +} + +static void gpio_usbotg_vbus_inactive(void) +{ + if (board_is_mx53_arm2()) { + /* MX53 ARM2 CPU board */ + /* Disable OTG VBus with GPIO high */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_D22), 1); + } else if (board_is_mx53_evk_a()) { + /* MX53 EVK board ver A*/ + /* Disable OTG VBus with GPIO high */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 1); + } else if (board_is_mx53_evk_b()) { + /* MX53 EVK board ver B*/ + /* Disable OTG VBus with GPIO low */ + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_EIM_A23), 0); + } +} + + +void mx53_gpio_usbotg_driver_vbus(bool on) +{ + if (on) + gpio_usbotg_vbus_active(); + else + gpio_usbotg_vbus_inactive(); +} +EXPORT_SYMBOL(mx53_gpio_usbotg_driver_vbus); + +void mx53_gpio_host1_driver_vbus(bool on) +{ + if (on) + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_2), 1); + else + gpio_set_value(IOMUX_TO_GPIO(MX53_PIN_ATA_DA_2), 0); +} +EXPORT_SYMBOL(mx53_gpio_host1_driver_vbus); diff --git a/arch/arm/mach-mx5/pm.c b/arch/arm/mach-mx5/pm.c index a63d6e725e8f..2839bffeda62 100644 --- a/arch/arm/mach-mx5/pm.c +++ b/arch/arm/mach-mx5/pm.c @@ -25,9 +25,11 @@ #include <asm/tlb.h> #include <asm/mach/map.h> #include <mach/hardware.h> -#include "crm_regs.h" #include "mach/irqs.h" +#define MXC_SRPG_EMPGC0_SRPGCR (IO_ADDRESS(GPC_BASE_ADDR) + 0x2C0) +#define MXC_SRPG_EMPGC1_SRPGCR (IO_ADDRESS(GPC_BASE_ADDR) + 0x2D0) + static struct cpu_wp *cpu_wp_tbl; static struct clk *cpu_clk; diff --git a/arch/arm/mach-mx5/sdma_script_code_mx50.h b/arch/arm/mach-mx5/sdma_script_code_mx50.h new file mode 100644 index 000000000000..bac8c6f87bda --- /dev/null +++ b/arch/arm/mach-mx5/sdma_script_code_mx50.h @@ -0,0 +1,130 @@ +/* + * 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. + */ + +/*! + * @file sdma_script_code.h + * @brief This file contains functions of SDMA scripts code initialization + * + * The file was generated automatically. Based on sdma scripts library. + * + * @ingroup SDMA + */ +/******************************************************************************* + + SDMA RELEASE LABEL: "SDMA_CODEX.01.00.00" + +*******************************************************************************/ + +#ifndef SDMA_SCRIPT_CODE_MX50_H +#define SDMA_SCRIPT_CODE_MX50_H + + +/*! +* SDMA ROM scripts start addresses and sizes +*/ + +#define start_ADDR_MX50 0 +#define start_SIZE_MX50 18 + +#define core_ADDR_MX50 80 +#define core_SIZE_MX50 232 + +#define common_ADDR_MX50 312 +#define common_SIZE_MX50 330 + +#define ap_2_ap_ADDR_MX50 642 +#define ap_2_ap_SIZE_MX50 41 + +#define app_2_mcu_ADDR_MX50 683 +#define app_2_mcu_SIZE_MX50 64 + +#define mcu_2_app_ADDR_MX50 747 +#define mcu_2_app_SIZE_MX50 70 + +#define uart_2_mcu_ADDR_MX50 817 +#define uart_2_mcu_SIZE_MX50 74 + +#define shp_2_mcu_ADDR_MX50 891 +#define shp_2_mcu_SIZE_MX50 69 + +#define mcu_2_shp_ADDR_MX50 960 +#define mcu_2_shp_SIZE_MX50 72 + +#define uartsh_2_mcu_ADDR_MX50 1032 +#define uartsh_2_mcu_SIZE_MX50 68 + +#define loop_DMAs_routines_ADDR_MX50 1100 +#define loop_DMAs_routines_SIZE_MX50 227 + +#define test_ADDR_MX50 1327 +#define test_SIZE_MX50 63 + +#define signature_ADDR_MX50 1023 +#define signature_SIZE_MX50 1 + +/*! +* SDMA RAM scripts start addresses and sizes +*/ + +#define mcu_2_ssiapp_ADDR_MX50 6144 +#define mcu_2_ssiapp_SIZE_MX50 96 + +#define mcu_2_ssish_ADDR_MX50 6240 +#define mcu_2_ssish_SIZE_MX50 95 + +/*! +* SDMA RAM image start address and size +*/ + +#define RAM_CODE_START_ADDR_MX50 6144 +#define RAM_CODE_SIZE_MX50 191 + +/*! +* Buffer that holds the SDMA RAM image +*/ +__attribute__ ((__aligned__(4))) +static const short sdma_code_mx50[] = +{ +0xc1e3, 0x57db, 0x52f3, 0x6a01, 0x008f, 0x00d5, 0x7d01, 0x008d, +0x05a0, 0x5deb, 0x0478, 0x7d03, 0x0479, 0x7d2c, 0x7c36, 0x0479, +0x7c1f, 0x56ee, 0x0f00, 0x0660, 0x7d05, 0x6509, 0x7e43, 0x620a, +0x7e41, 0x981e, 0x620a, 0x7e3e, 0x6509, 0x7e3c, 0x0512, 0x0512, +0x02ad, 0x0760, 0x7d03, 0x55fb, 0x6dd3, 0x9829, 0x55fb, 0x1d04, +0x6dd3, 0x6ac8, 0x7f2f, 0x1f01, 0x2003, 0x4800, 0x7ce4, 0x9851, +0x55fb, 0x6dd7, 0x0015, 0x7805, 0x6209, 0x6ac8, 0x6209, 0x6ac8, +0x6dd7, 0x9850, 0x55fb, 0x6dd7, 0x0015, 0x0015, 0x7805, 0x620a, +0x6ac8, 0x620a, 0x6ac8, 0x6dd7, 0x9850, 0x55fb, 0x6dd7, 0x0015, +0x0015, 0x0015, 0x7805, 0x620b, 0x6ac8, 0x620b, 0x6ac8, 0x6dd7, +0x7c09, 0x6ddf, 0x7f07, 0x0000, 0x55eb, 0x4d00, 0x7d07, 0xc1fa, +0x57db, 0x9804, 0x0007, 0x68cc, 0x680c, 0xc213, 0xc20a, 0x9801, +0xc1d9, 0xc1e3, 0x57db, 0x52f3, 0x6a21, 0x008f, 0x00d5, 0x7d01, +0x008d, 0x05a0, 0x5deb, 0x56fb, 0x0478, 0x7d03, 0x0479, 0x7d32, +0x7c39, 0x0479, 0x7c28, 0x0b70, 0x0311, 0x53eb, 0x0f00, 0x0360, +0x7d05, 0x6509, 0x7e3f, 0x620a, 0x7e3d, 0x9882, 0x620a, 0x7e3a, +0x6509, 0x7e38, 0x0512, 0x0512, 0x02ad, 0x0760, 0x7d0a, 0x5a06, +0x7f31, 0x1f01, 0x2003, 0x4800, 0x7cea, 0x0b70, 0x0311, 0x5313, +0x98b3, 0x5a26, 0x7f27, 0x1f01, 0x2003, 0x4800, 0x7ce0, 0x0b70, +0x0311, 0x5313, 0x98b3, 0x0015, 0x7804, 0x6209, 0x5a06, 0x6209, +0x5a26, 0x98b2, 0x0015, 0x0015, 0x7804, 0x620a, 0x5a06, 0x620a, +0x5a26, 0x98b2, 0x0015, 0x0015, 0x0015, 0x7804, 0x620b, 0x5a06, +0x620b, 0x5a26, 0x7c07, 0x0000, 0x55eb, 0x4d00, 0x7d06, 0xc1fa, +0x57db, 0x9865, 0x0007, 0x680c, 0xc213, 0xc20a, 0x9862 +}; +#endif diff --git a/arch/arm/mach-mx5/sdram_autogating.c b/arch/arm/mach-mx5/sdram_autogating.c index fa9f0ccfe283..0b05d791c4f9 100644 --- a/arch/arm/mach-mx5/sdram_autogating.c +++ b/arch/arm/mach-mx5/sdram_autogating.c @@ -80,6 +80,8 @@ int sdram_autogating_active() void start_sdram_autogating() { + if (cpu_is_mx50()) + return; if (sdram_autogating_paused) { enable(); sdram_autogating_paused = 0; @@ -88,6 +90,9 @@ void start_sdram_autogating() void stop_sdram_autogating() { + if (cpu_is_mx50()) + return; + if (sdram_autogating_is_active) { sdram_autogating_paused = 1; disable(); diff --git a/arch/arm/mach-mx5/serial.c b/arch/arm/mach-mx5/serial.c index 053829cd3b4e..6d01de55c50b 100644 --- a/arch/arm/mach-mx5/serial.c +++ b/arch/arm/mach-mx5/serial.c @@ -23,7 +23,6 @@ #include <mach/hardware.h> #include <mach/mxc_uart.h> #include "serial.h" -#include "board-mx53_evk.h" #if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) @@ -42,13 +41,12 @@ static uart_mxc_port mxc_ports[] = { .flags = ASYNC_BOOT_AUTOCONF, .line = 0, }, - .ints_muxed = UART1_MUX_INTS, + .ints_muxed = 1, .mode = UART1_MODE, .ir_mode = UART1_IR, .enabled = UART1_ENABLED, - .hardware_flow = UART1_HW_FLOW, .cts_threshold = UART1_UCR4_CTSTL, - .dma_enabled = UART1_DMA_ENABLE, + .dma_enabled = UART1_DMA_ENABLED, .dma_rxbuf_size = UART1_DMA_RXBUFSIZE, .rx_threshold = UART1_UFCR_RXTL, .tx_threshold = UART1_UFCR_TXTL, @@ -63,13 +61,12 @@ static uart_mxc_port mxc_ports[] = { .flags = ASYNC_BOOT_AUTOCONF, .line = 1, }, - .ints_muxed = UART2_MUX_INTS, + .ints_muxed = 1, .mode = UART2_MODE, .ir_mode = UART2_IR, .enabled = UART2_ENABLED, - .hardware_flow = UART2_HW_FLOW, .cts_threshold = UART2_UCR4_CTSTL, - .dma_enabled = UART2_DMA_ENABLE, + .dma_enabled = UART2_DMA_ENABLED, .dma_rxbuf_size = UART2_DMA_RXBUFSIZE, .rx_threshold = UART2_UFCR_RXTL, .tx_threshold = UART2_UFCR_TXTL, @@ -84,13 +81,12 @@ static uart_mxc_port mxc_ports[] = { .flags = ASYNC_BOOT_AUTOCONF, .line = 2, }, - .ints_muxed = UART3_MUX_INTS, + .ints_muxed = 1, .mode = UART3_MODE, .ir_mode = UART3_IR, .enabled = UART3_ENABLED, - .hardware_flow = UART3_HW_FLOW, .cts_threshold = UART3_UCR4_CTSTL, - .dma_enabled = UART3_DMA_ENABLE, + .dma_enabled = UART3_DMA_ENABLED, .dma_rxbuf_size = UART3_DMA_RXBUFSIZE, .rx_threshold = UART3_UFCR_RXTL, .tx_threshold = UART3_UFCR_TXTL, @@ -105,13 +101,11 @@ static uart_mxc_port mxc_ports[] = { .flags = ASYNC_BOOT_AUTOCONF, .line = 3, }, - .ints_muxed = UART4_MUX_INTS, - .mode = UART4_MODE, - .ir_mode = UART4_IR, - .enabled = UART4_ENABLED, - .hardware_flow = UART4_HW_FLOW, + .ints_muxed = 1, + .mode = MODE_DCE, + .ir_mode = NO_IRDA, + .enabled = 1, .cts_threshold = UART4_UCR4_CTSTL, - .dma_enabled = UART4_DMA_ENABLE, .dma_rxbuf_size = UART4_DMA_RXBUFSIZE, .rx_threshold = UART4_UFCR_RXTL, .tx_threshold = UART4_UFCR_TXTL, @@ -126,13 +120,11 @@ static uart_mxc_port mxc_ports[] = { .flags = ASYNC_BOOT_AUTOCONF, .line = 4, }, - .ints_muxed = UART5_MUX_INTS, - .mode = UART5_MODE, - .ir_mode = UART5_IR, - .enabled = UART5_ENABLED, - .hardware_flow = UART5_HW_FLOW, + .ints_muxed = 1, + .mode = MODE_DCE, + .ir_mode = NO_IRDA, + .enabled = 1, .cts_threshold = UART5_UCR4_CTSTL, - .dma_enabled = UART5_DMA_ENABLE, .dma_rxbuf_size = UART5_DMA_RXBUFSIZE, .rx_threshold = UART5_UFCR_RXTL, .tx_threshold = UART5_UFCR_TXTL, @@ -149,18 +141,9 @@ static struct resource mxc_uart_resources1[] = { .flags = IORESOURCE_MEM, }, { - .start = UART1_INT1, + .start = MXC_INT_UART1, .flags = IORESOURCE_IRQ, }, - { - .start = UART1_INT2, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART1_INT3, - .flags = IORESOURCE_IRQ, - }, - }; static struct platform_device mxc_uart_device1 = { @@ -180,15 +163,7 @@ static struct resource mxc_uart_resources2[] = { .flags = IORESOURCE_MEM, }, { - .start = UART2_INT1, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART2_INT2, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART2_INT3, + .start = MXC_INT_UART2, .flags = IORESOURCE_IRQ, }, }; @@ -210,15 +185,7 @@ static struct resource mxc_uart_resources3[] = { .flags = IORESOURCE_MEM, }, { - .start = UART3_INT1, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART3_INT2, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART3_INT3, + .start = MXC_INT_UART3, .flags = IORESOURCE_IRQ, }, }; @@ -240,15 +207,7 @@ static struct resource mxc_uart_resources4[] = { .flags = IORESOURCE_MEM, }, { - .start = UART4_INT1, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART4_INT2, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART4_INT3, + .start = MXC_INT_UART4, .flags = IORESOURCE_IRQ, }, }; @@ -270,15 +229,7 @@ static struct resource mxc_uart_resources5[] = { .flags = IORESOURCE_MEM, }, { - .start = UART5_INT1, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART5_INT2, - .flags = IORESOURCE_IRQ, - }, - { - .start = UART5_INT3, + .start = MXC_INT_UART5, .flags = IORESOURCE_IRQ, }, }; @@ -295,7 +246,7 @@ static struct platform_device mxc_uart_device5 = { static int __init mxc_init_uart(void) { - if (cpu_is_mx53()) { + if (cpu_is_mx53() || cpu_is_mx50()) { mxc_uart_resources1[0].start -= 0x20000000; mxc_uart_resources1[0].end -= 0x20000000; mxc_uart_resources2[0].start -= 0x20000000; @@ -311,16 +262,10 @@ static int __init mxc_init_uart(void) /* Register all the MXC UART platform device structures */ platform_device_register(&mxc_uart_device1); platform_device_register(&mxc_uart_device2); -#if UART3_ENABLED == 1 platform_device_register(&mxc_uart_device3); -#endif /* UART3_ENABLED */ if (cpu_is_mx53()) { -#if UART4_ENABLED == 1 platform_device_register(&mxc_uart_device4); -#endif /* UART4_ENABLED */ -#if UART5_ENABLED == 1 platform_device_register(&mxc_uart_device5); -#endif /* UART5_ENABLED */ } return 0; } diff --git a/arch/arm/mach-mx5/serial.h b/arch/arm/mach-mx5/serial.h index aa97228e3865..b74cd0b2661c 100644 --- a/arch/arm/mach-mx5/serial.h +++ b/arch/arm/mach-mx5/serial.h @@ -14,17 +14,8 @@ #ifndef __ARCH_ARM_MACH_MX51_SERIAL_H__ #define __ARCH_ARM_MACH_MX51_SERIAL_H__ -#include <mach/mxc_uart.h> - /* UART 1 configuration */ /*! - * This option allows to choose either an interrupt-driven software controlled - * hardware flow control (set this option to 0) or hardware-driven hardware - * flow control (set this option to 1). - */ -/* UART used as wakeup source */ -#define UART1_HW_FLOW 0 -/*! * This specifies the threshold at which the CTS pin is deasserted by the * RXFIFO. Set this value in Decimal to anything from 0 to 32 for * hardware-driven hardware flow control. Read the HW spec while specifying @@ -33,10 +24,6 @@ */ #define UART1_UCR4_CTSTL 16 /*! - * This is option to enable (set this option to 1) or disable DMA data transfer - */ -#define UART1_DMA_ENABLE 0 -/*! * Specify the size of the DMA receive buffer. The minimum buffer size is 512 * bytes. The buffer size should be a multiple of 256. */ @@ -56,88 +43,28 @@ */ #define UART1_UFCR_TXTL 16 /* UART 2 configuration */ -#define UART2_HW_FLOW 0 -#define UART2_UCR4_CTSTL -1 -#define UART2_DMA_ENABLE 0 +#define UART2_UCR4_CTSTL 16 #define UART2_DMA_RXBUFSIZE 512 #define UART2_UFCR_RXTL 16 #define UART2_UFCR_TXTL 16 /* UART 3 configuration */ -#define UART3_HW_FLOW 1 #define UART3_UCR4_CTSTL 16 -#define UART3_DMA_ENABLE 1 #define UART3_DMA_RXBUFSIZE 1024 #define UART3_UFCR_RXTL 16 #define UART3_UFCR_TXTL 16 /* UART 4 configuration */ -#define UART4_HW_FLOW 0 #define UART4_UCR4_CTSTL -1 -#define UART4_DMA_ENABLE 0 #define UART4_DMA_RXBUFSIZE 512 #define UART4_UFCR_RXTL 16 #define UART4_UFCR_TXTL 16 /* UART 5 configuration */ -#define UART5_HW_FLOW 0 #define UART5_UCR4_CTSTL -1 -#define UART5_DMA_ENABLE 0 #define UART5_DMA_RXBUFSIZE 512 #define UART5_UFCR_RXTL 16 #define UART5_UFCR_TXTL 16 -/* - * UART Chip level Configuration that a user may not have to edit. These - * configuration vary depending on how the UART module is integrated with - * the ARM core - */ -/* - * Is the MUXED interrupt output sent to the ARM core - */ -#define INTS_NOTMUXED 0 -#define INTS_MUXED 1 -/* UART 1 configuration */ -/*! - * This define specifies whether the muxed ANDed interrupt line or the - * individual interrupts from the UART port is integrated with the ARM core. - * There exists a define like this for each UART port. Valid values that can - * be used are \b INTS_NOTMUXED or \b INTS_MUXED. - */ -#define UART1_MUX_INTS INTS_MUXED -/*! - * This define specifies the transmitter interrupt number or the interrupt - * number of the ANDed interrupt in case the interrupts are muxed. There exists - * a define like this for each UART port. - */ -#define UART1_INT1 MXC_INT_UART1 -/*! - * This define specifies the receiver interrupt number. If the interrupts of - * the UART are muxed, then we specify here a dummy value -1. There exists a - * define like this for each UART port. - */ -#define UART1_INT2 -1 -/*! - * This specifies the master interrupt number. If the interrupts of the UART - * are muxed, then we specify here a dummy value of -1. There exists a define - * like this for each UART port. - */ -#define UART1_INT3 -1 -/* UART 2 configuration */ -#define UART2_MUX_INTS INTS_MUXED -#define UART2_INT1 MXC_INT_UART2 -#define UART2_INT2 -1 -#define UART2_INT3 -1 -/* UART 3 configuration */ -#define UART3_MUX_INTS INTS_MUXED -#define UART3_INT1 MXC_INT_UART3 -#define UART3_INT2 -1 -#define UART3_INT3 -1 -/* UART 4 configuration */ -#define UART4_MUX_INTS INTS_MUXED -#define UART4_INT1 MXC_INT_UART4 -#define UART4_INT2 -1 -#define UART4_INT3 -1 -/* UART 5 configuration */ -#define UART5_MUX_INTS INTS_MUXED -#define UART5_INT1 MXC_INT_UART5 -#define UART5_INT2 -1 -#define UART5_INT3 -1 + +#ifdef CONFIG_MODULE_CCXMX51 +#include "board-ccwmx51.h" +#endif #endif /* __ARCH_ARM_MACH_MX51_SERIAL_H__ */ diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c index 669be9c4c9cb..da27fc4605a3 100644 --- a/arch/arm/mach-mx5/system.c +++ b/arch/arm/mach-mx5/system.c @@ -171,7 +171,8 @@ void arch_reset(char mode) /* Workaround to reset NFC_CONFIG3 register * due to the chip warm reset does not reset it */ - __raw_writel(0x20600, IO_ADDRESS(NFC_BASE_ADDR) + 0x28); + if (cpu_is_mx51() || cpu_is_mx53()) + __raw_writel(0x20600, IO_ADDRESS(NFC_BASE_ADDR) + 0x28); /* Assert SRS signal */ mxc_wd_reset(); diff --git a/arch/arm/mach-mx5/usb.h b/arch/arm/mach-mx5/usb.h index f451e6fe8582..6115d3375c05 100644 --- a/arch/arm/mach-mx5/usb.h +++ b/arch/arm/mach-mx5/usb.h @@ -30,6 +30,9 @@ extern void __init mx5_usb_dr_init(void); extern void __init mx5_usbh1_init(void); extern void __init mx5_usbh2_init(void); +typedef void (*driver_vbus_func)(bool); +extern void mx5_set_host1_vbus_func(driver_vbus_func); +extern void mx5_set_otghost_vbus_func(driver_vbus_func); /* * Used to set pdata->operating_mode before registering the platform_device. * If OTG is configured, the controller operates in OTG mode, diff --git a/arch/arm/mach-mx5/usb_dr.c b/arch/arm/mach-mx5/usb_dr.c index 658583b65ab6..0878fd6e0d38 100644 --- a/arch/arm/mach-mx5/usb_dr.c +++ b/arch/arm/mach-mx5/usb_dr.c @@ -140,6 +140,13 @@ static void usbotg_clock_gate(bool on) } #endif +void mx5_set_otghost_vbus_func(driver_vbus_func driver_vbus) +{ +#if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_EHCI_ARC_OTG) || defined(CONFIG_USB_GADGET_ARC) + dr_utmi_config.platform_driver_vbus = driver_vbus; +#endif +} + void __init mx5_usb_dr_init(void) { #ifdef CONFIG_USB_OTG diff --git a/arch/arm/mach-mx5/usb_h1.c b/arch/arm/mach-mx5/usb_h1.c index 7f0c463d45c1..52a2bcafd765 100644 --- a/arch/arm/mach-mx5/usb_h1.c +++ b/arch/arm/mach-mx5/usb_h1.c @@ -24,7 +24,6 @@ #include "iomux.h" #include "mx51_pins.h" - /* * USB Host1 HS port */ @@ -76,19 +75,25 @@ static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable) static void usbotg_clock_gate(bool on) { - struct clk *usboh3_clk = clk_get(NULL, "usboh3_clk"); - struct clk *usb_ahb_clk = clk_get(NULL, "usb_ahb_clk"); - + struct clk *usb_clk; if (on) { - clk_enable(usb_ahb_clk); - clk_enable(usboh3_clk); + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + } else { - clk_disable(usboh3_clk); - clk_disable(usb_ahb_clk); - } + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); - clk_put(usboh3_clk); - clk_put(usb_ahb_clk); + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + } } static int fsl_usb_host_init_ext(struct platform_device *pdev) @@ -109,6 +114,10 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev) usb_clk = clk_get(NULL, "usb_utmi_clk"); clk_disable(usb_clk); clk_put(usb_clk); + } else if (cpu_is_mx50()) { + usb_clk = clk_get(&pdev->dev, "usb_phy2_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); } ret = fsl_usb_host_init(pdev); @@ -143,7 +152,12 @@ static void fsl_usb_host_uninit_ext(struct fsl_usb2_platform_data *pdata) usb_clk = clk_get(&pdata->pdev->dev, "usb_phy2_clk"); clk_disable(usb_clk); clk_put(usb_clk); + } else if (cpu_is_mx50()) { + usb_clk = clk_get(&pdata->pdev->dev, "usb_phy2_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); } + fsl_usb_host_uninit(pdata); } @@ -159,6 +173,10 @@ static struct fsl_usb2_platform_data usbh1_config = { .transceiver = "utmi", }; +void mx5_set_host1_vbus_func(driver_vbus_func driver_vbus) +{ + usbh1_config.platform_driver_vbus = driver_vbus; +} void __init mx5_usbh1_init(void) { if (cpu_is_mx51()) { |