diff options
Diffstat (limited to 'arch/arm/mach-mx5')
33 files changed, 6316 insertions, 1464 deletions
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 5dd3e0fa0b99..7152e3c0f34f 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -2,10 +2,15 @@ if ARCH_MX5 config ARCH_MX51 bool "MX51" + select ARCH_MXC_IOMUX_V3 config ARCH_MX53 bool "MX53" +config ARCH_MX50 + bool + select ARCH_HAS_RNGC + config FORCE_MAX_ZONEORDER int "MAX_ORDER" default "13" @@ -21,7 +26,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 +50,31 @@ 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_MX50_RDP + bool "Support MX50 Reference Design Platform" + select ARCH_MX50 + help + Include support for MX50 RDP platform. This includes specific + configurations for the board and its peripherals. + 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 +83,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 +150,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 +164,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 +182,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 +299,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 +319,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..90baa14638fe 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -4,12 +4,21 @@ # 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 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_ARCH_MX51) += clock.o suspend.o +obj-$(CONFIG_ARCH_MX53) += clock.o suspend.o +obj-$(CONFIG_ARCH_MX50) += clock_mx50.o dmaengine.o dma-apbh.o mx50_suspend.o mx50_ddr_freq.o mx50_wfi.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_MX51_BABBAGE) += mx51_babbage.o mx51_babbage_pmic_mc13892.o +obj-$(CONFIG_MACH_MX53_EVK) += mx53_evk.o mx53_evk_pmic_mc13892.o +obj-$(CONFIG_MACH_MX50_ARM2) += mx50_arm2.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 +obj-$(CONFIG_MACH_MX50_RDP) += mx50_rdp.o mx50_rdp_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..ec2addfd977b 100644 --- a/arch/arm/mach-mx5/bus_freq.c +++ b/arch/arm/mach-mx5/bus_freq.c @@ -27,45 +27,56 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/iram_alloc.h> +#include <linux/mutex.h> #include <mach/hardware.h> #include <mach/clock.h> #include <mach/mxc_dvfs.h> #include <mach/sdram_autogating.h> +#include <asm/mach/map.h> +#include <asm/cacheflush.h> +#include <asm/tlb.h> #include "crm_regs.h" -#define LP_NORMAL_CLK 133000000 -#define LP_MED_CLK 83125000 +#define LP_LOW_VOLTAGE 1050000 +#define LP_NORMAL_VOLTAGE 1250000 #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 #define AHB_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV #define EMI_SLOW_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV #define NFC_CLK_NORMAL_DIV 4 +#define SPIN_DELAY 1000000 /* in nanoseconds */ + +DEFINE_SPINLOCK(ddr_freq_lock); + +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 *pll1; static struct clk *pll2; static struct clk *pll3; +static struct clk *pll4; static struct clk *main_bus_clk; static struct clk *axi_a_clk; static struct clk *axi_b_clk; static struct clk *cpu_clk; static struct clk *ddr_hf_clk; -static struct clk *nfc_clk; static struct clk *ahb_clk; -static struct clk *vpu_clk; -static struct clk *vpu_core_clk; -static struct clk *emi_slow_clk; static struct clk *ddr_clk; -static struct clk *ipu_clk; static struct clk *periph_apm_clk; static struct clk *lp_apm; static struct clk *osc; static struct clk *gpc_dvfs_clk; static struct clk *emi_garb_clk; +static void __iomem *pll1_base; +static void __iomem *pll4_base; struct regulator *lp_regulator; int low_bus_freq_mode; @@ -77,14 +88,28 @@ char *lp_reg_id = "SW2"; static struct cpu_wp *cpu_wp_tbl; static struct device *busfreq_dev; static int busfreq_suspended; +static int cpu_podf; /* 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; + +void enter_lpapm_mode_mx50(void); +void enter_lpapm_mode_mx51(void); +void exit_lpapm_mode_mx50(void); +void exit_lpapm_mode_mx51(void); +void *ddr_freq_change_iram_base; +void (*change_ddr_freq)(void *ccm_addr, void *databahn_addr, u32 freq) = NULL; + +extern void mx50_ddr_freq_change(u32 ccm_base, + u32 databahn_addr, u32 freq); extern int dvfs_core_is_active; extern struct cpu_wp *(*get_cpu_wp)(int *wp); -extern int cpu_wp_nr; +extern void propagate_rate(struct clk *tclk); +extern void __iomem *ccm_base; +extern void __iomem *databahn_base; struct dvfs_wp dvfs_core_setpoint[] = { {33, 8, 33, 10, 10, 0x08}, @@ -92,121 +117,267 @@ 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; + struct timespec nstimeofday; + struct timespec curtime; if (busfreq_suspended) return 0; if (bus_freq_scaling_initialized) { - if (clk_get_rate(cpu_clk) != cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) + /* 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; + } 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)); - /* Set PLL3 to 133Mhz if no-one is using it. */ - if (clk_get_usecount(pll3) == 0) { + if ((clk_get_usecount(pll3) == 0) && !cpu_is_mx53()) { u32 pll3_rate = clk_get_rate(pll3); clk_enable(pll3); clk_set_rate(pll3, clk_round_rate(pll3, 133000000)); - /* Set the parent of Periph_apm_clk to be PLL3 */ - clk_set_parent(periph_apm_clk, pll3); - clk_set_parent(main_bus_clk, periph_apm_clk); - - /* Set the AHB dividers to be 1. */ - /* Set the dividers to be 1, so the clock rates - * are at 133MHz. - */ - reg = __raw_readl(MXC_CCM_CBCDR); - reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK - | MXC_CCM_CBCDR_AXI_B_PODF_MASK - | MXC_CCM_CBCDR_AHB_PODF_MASK - | MXC_CCM_CBCDR_EMI_PODF_MASK - | MXC_CCM_CBCDR_NFC_PODF_OFFSET); - reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET - | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET - | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET - | 0 << MXC_CCM_CBCDR_EMI_PODF_OFFSET - | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET); - __raw_writel(reg, MXC_CCM_CBCDR); - - clk_enable(emi_garb_clk); - while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F) - udelay(10); - clk_disable(emi_garb_clk); - - /* Set the source of Periph_APM_Clock to be lp-apm. */ - clk_set_parent(periph_apm_clk, lp_apm); + if (cpu_is_mx50()) + enter_lpapm_mode_mx50(); + else + enter_lpapm_mode_mx51(); /* Set PLL3 back to original rate. */ clk_set_rate(pll3, clk_round_rate(pll3, pll3_rate)); clk_disable(pll3); + } else if (cpu_is_mx53()) { + /*Change the DDR freq to 133Mhz. */ + clk_set_rate(ddr_hf_clk, + clk_round_rate(ddr_hf_clk, ddr_low_rate)); + + /* move cpu clk to pll2, 400 / 3 = 133Mhz for cpu */ + clk_set_parent(pll1_sw_clk, pll2); + + cpu_podf = __raw_readl(MXC_CCM_CACRR); + reg = __raw_readl(MXC_CCM_CDHIPR); + if ((reg & MXC_CCM_CDHIPR_ARM_PODF_BUSY) == 0) + __raw_writel(0x2, MXC_CCM_CACRR); + else + printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n"); + + /* ahb = 400/8, axi_b = 400/8, axi_a = 133*/ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK + | MXC_CCM_CBCDR_AXI_B_PODF_MASK + | MXC_CCM_CBCDR_AHB_PODF_MASK); + reg |= (2 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + | 7 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + | 7 << MXC_CCM_CBCDR_AHB_PODF_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & + (MXC_CCM_CDHIPR_AXI_A_PODF_BUSY | + MXC_CCM_CDHIPR_AXI_B_PODF_BUSY | + MXC_CCM_CDHIPR_AHB_PODF_BUSY)) { + getnstimeofday(&curtime); + if (curtime.tv_nsec - nstimeofday.tv_nsec + > SPIN_DELAY) + panic("low bus freq set rate error\n"); + } + + /* keep this infront of propagating */ low_bus_freq_mode = 1; high_bus_freq_mode = 0; + + propagate_rate(main_bus_clk); + propagate_rate(pll1_sw_clk); + + if (clk_get_usecount(pll1) == 0) { + reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL); + reg &= ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL); + } + if (clk_get_usecount(pll4) == 0) { + reg = __raw_readl(pll4_base + MXC_PLL_DP_CTL); + reg &= ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pll4_base + MXC_PLL_DP_CTL); + } } } return 0; } +void enter_lpapm_mode_mx50() +{ + u32 reg; + unsigned long flags; + + spin_lock_irqsave(&ddr_freq_lock, flags); + + /* Set the parent of main_bus_clk to be PLL3 */ + clk_set_parent(main_bus_clk, pll3); + + /* Set the AHB dividers to be 1. */ + /* Set the dividers to be 1, so the clock rates + * are at 133MHz. + */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK + | MXC_CCM_CBCDR_AXI_B_PODF_MASK + | MXC_CCM_CBCDR_AHB_PODF_MASK + | MX50_CCM_CBCDR_WEIM_PODF_MASK); + reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET + | 0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + while (__raw_readl(MXC_CCM_CDHIPR) & 0x0F) + udelay(10); + low_bus_freq_mode = 1; + high_bus_freq_mode = 0; + + /* Set the source of main_bus_clk to be lp-apm. */ + clk_set_parent(main_bus_clk, lp_apm); + + /* Set SYS_CLK to 24MHz. sourced from XTAL*/ + /* Turn on the XTAL_CLK_GATE. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg |= 3 << MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_OFFSET; + __raw_writel(reg, MXC_CCM_CLK_SYS); + + /* Set the divider. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg &= ~MXC_CCM_CLK_SYS_DIV_XTAL_MASK; + reg |= 1 << MXC_CCM_CLK_SYS_DIV_XTAL_OFFSET; + __raw_writel(reg, MXC_CCM_CLK_SYS); + while (__raw_readl(MXC_CCM_CSR2) & 0x1) + udelay(10); + + /* Set the source to be XTAL. */ + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + reg &= ~0x1; + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + while (!(__raw_readl(MXC_CCM_CSR2) & 0x400)) + udelay(10); + + /* Turn OFF the PLL_CLK_GATE. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg &= ~MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_CLK_SYS); + spin_unlock_irqrestore(&ddr_freq_lock, flags); + +} + +void enter_lpapm_mode_mx51() +{ + u32 reg; + + /*Change the DDR freq to 133Mhz. */ + clk_set_rate(ddr_hf_clk, + clk_round_rate(ddr_hf_clk, ddr_low_rate)); + + /* Set the parent of Periph_apm_clk to be PLL3 */ + clk_set_parent(periph_apm_clk, pll3); + clk_set_parent(main_bus_clk, periph_apm_clk); + + /* Set the dividers to be 1, so the clock rates + * are at 133MHz. + */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK + | MXC_CCM_CBCDR_AXI_B_PODF_MASK + | MXC_CCM_CBCDR_AHB_PODF_MASK + | MXC_CCM_CBCDR_EMI_PODF_MASK + | MXC_CCM_CBCDR_NFC_PODF_OFFSET); + reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET + | 0 << MXC_CCM_CBCDR_EMI_PODF_OFFSET + | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + clk_enable(emi_garb_clk); + while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F) + udelay(10); + clk_disable(emi_garb_clk); + + /* Set the source of Periph_APM_Clock to be lp-apm. */ + clk_set_parent(periph_apm_clk, lp_apm); +} + int set_high_bus_freq(int high_bus_freq) { u32 reg; + struct timespec nstimeofday; + struct timespec curtime; if (bus_freq_scaling_initialized) { + stop_sdram_autogating(); if (low_bus_freq_mode) { /* Relock PLL3 to 133MHz */ - if (clk_get_usecount(pll3) == 0) { + if ((clk_get_usecount(pll3) == 0) && !cpu_is_mx53()) { u32 pll3_rate = clk_get_rate(pll3); clk_enable(pll3); clk_set_rate(pll3, clk_round_rate(pll3, 133000000)); - clk_set_parent(periph_apm_clk, pll3); - /* Set the dividers to the default dividers */ + if (cpu_is_mx50()) + exit_lpapm_mode_mx50(); + else + exit_lpapm_mode_mx51(); + + /* Relock PLL3 to its original rate */ + clk_set_rate(pll3, + clk_round_rate(pll3, pll3_rate)); + clk_disable(pll3); + } else if (cpu_is_mx53()) { + /* move cpu clk to pll1 */ + reg = __raw_readl(MXC_CCM_CDHIPR); + if ((reg & MXC_CCM_CDHIPR_ARM_PODF_BUSY) == 0) + __raw_writel(cpu_podf & 0x7, + MXC_CCM_CACRR); + else + printk(KERN_DEBUG + "ARM_PODF still in busy!!!!\n"); + + clk_set_parent(pll1_sw_clk, pll1); + + /* ahb = 400/3, axi_b = 400/3, axi_a = 400*/ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK - | MXC_CCM_CBCDR_AHB_PODF_MASK - | MXC_CCM_CBCDR_EMI_PODF_MASK - | MXC_CCM_CBCDR_NFC_PODF_OFFSET); - reg |= (3 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET - | 4 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET - | 4 << MXC_CCM_CBCDR_AHB_PODF_OFFSET - | 4 << MXC_CCM_CBCDR_EMI_PODF_OFFSET - | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET); + | MXC_CCM_CBCDR_AHB_PODF_MASK); + reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + | 2 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + | 2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); - clk_enable(emi_garb_clk); - while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F) - udelay(10); - - low_bus_freq_mode = 0; - high_bus_freq_mode = 1; - clk_disable(emi_garb_clk); - - /*Set the main_bus_clk parent to be PLL2. */ - clk_set_parent(main_bus_clk, pll2); + getnstimeofday(&nstimeofday); + while (__raw_readl(MXC_CCM_CDHIPR) & + (MXC_CCM_CDHIPR_AXI_A_PODF_BUSY | + MXC_CCM_CDHIPR_AXI_B_PODF_BUSY | + MXC_CCM_CDHIPR_AHB_PODF_BUSY)) { + getnstimeofday(&curtime); + if (curtime.tv_nsec + - nstimeofday.tv_nsec + > SPIN_DELAY) + panic("bus freq error\n"); + } + + /* keep this infront of propagating */ + low_bus_freq_mode = 1; + high_bus_freq_mode = 0; - /* Relock PLL3 to its original rate */ - clk_set_rate(pll3, - clk_round_rate(pll3, pll3_rate)); - clk_disable(pll3); + propagate_rate(main_bus_clk); + propagate_rate(pll1_sw_clk); + /*Change the DDR freq to mormal_rate*/ + clk_set_rate(ddr_hf_clk, + clk_round_rate(ddr_hf_clk, ddr_normal_rate)); } - - /*Change the DDR freq to 200MHz*/ - clk_set_rate(ddr_hf_clk, - clk_round_rate(ddr_hf_clk, DDR_NORMAL_CLK)); start_dvfs_per(); } if (bus_freq_scaling_is_active) { @@ -218,24 +389,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(); @@ -243,11 +418,105 @@ int set_high_bus_freq(int high_bus_freq) return 0; } +void exit_lpapm_mode_mx50() +{ + u32 reg; + unsigned long flags; + + spin_lock_irqsave(&ddr_freq_lock, flags); + + /* Set SYS_CLK to source from PLL1 */ + /* Set sys_clk back to 200MHz. */ + /* Set the divider to 4. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK; + reg |= 0x4 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET; + __raw_writel(reg, MXC_CCM_CLK_SYS); + udelay(100); + + /* Turn ON the PLL CLK_GATE. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg |= 3 << MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_OFFSET; + __raw_writel(reg, MXC_CCM_CLK_SYS); + + /* Source the SYS_CLK from PLL */ + reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS); + reg |= 0x3; + __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS); + while (__raw_readl(MXC_CCM_CSR2) & 0x400) + udelay(10); + + /* Turn OFF the XTAL_CLK_GATE. */ + reg = __raw_readl(MXC_CCM_CLK_SYS); + reg &= ~MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK; + __raw_writel(reg, MXC_CCM_CLK_SYS); + + clk_set_parent(main_bus_clk, pll3); + + /* Set the dividers to the default dividers */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK + | MXC_CCM_CBCDR_AXI_B_PODF_MASK + | MXC_CCM_CBCDR_AHB_PODF_MASK + | MX50_CCM_CBCDR_WEIM_PODF_MASK); + reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET + |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) + udelay(10); + + low_bus_freq_mode = 0; + high_bus_freq_mode = 1; + + /*Set the main_bus_clk parent to be PLL2. */ + clk_set_parent(main_bus_clk, pll2); + spin_unlock_irqrestore(&ddr_freq_lock, flags); + + udelay(100); +} + +void exit_lpapm_mode_mx51() +{ + u32 reg; + + clk_set_parent(periph_apm_clk, pll3); + + /* Set the dividers to the default dividers */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK + | MXC_CCM_CBCDR_AXI_B_PODF_MASK + | MXC_CCM_CBCDR_AHB_PODF_MASK + | MXC_CCM_CBCDR_EMI_PODF_MASK + | MXC_CCM_CBCDR_NFC_PODF_OFFSET); + reg |= (3 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET + | 4 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET + | 4 << MXC_CCM_CBCDR_AHB_PODF_OFFSET + | 4 << MXC_CCM_CBCDR_EMI_PODF_OFFSET + | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + clk_enable(emi_garb_clk); + while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F) + udelay(10); + + low_bus_freq_mode = 0; + high_bus_freq_mode = 1; + clk_disable(emi_garb_clk); + + /*Set the main_bus_clk parent to be PLL2. */ + clk_set_parent(main_bus_clk, pll2); + + /*Change the DDR freq to 200MHz*/ + clk_set_rate(ddr_hf_clk, + clk_round_rate(ddr_hf_clk, ddr_normal_rate)); +} + int low_freq_bus_used(void) { - if ((clk_get_usecount(ipu_clk) == 0) - && (clk_get_usecount(vpu_clk) == 0) - && (lp_high_freq == 0) + if ((lp_high_freq == 0) && (lp_med_freq == 0)) return 1; else @@ -273,8 +542,7 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev, { u32 reg; - - if (strstr(buf, "1") != NULL) { + if (strncmp(buf, "1", 1) == 0) { if (dvfs_per_active()) { printk(KERN_INFO "bus frequency scaling cannot be\ enabled when DVFS-PER is active\n"); @@ -288,12 +556,13 @@ static ssize_t bus_freq_scaling_enable_store(struct device *dev, clk_set_parent(main_bus_clk, pll2); bus_freq_scaling_is_active = 1; - } - else if (strstr(buf, "0") != NULL) { + set_high_bus_freq(0); + } else if (strncmp(buf, "0", 1) == 0) { if (bus_freq_scaling_is_active) set_high_bus_freq(1); bus_freq_scaling_is_active = 0; } + return size; } @@ -325,6 +594,12 @@ 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; + unsigned long iram_paddr; + + pll1_base = ioremap(MX53_BASE_ADDR(PLL1_BASE_ADDR), SZ_4K); + if (cpu_is_mx53()) + pll4_base = ioremap(MX53_BASE_ADDR(PLL4_BASE_ADDR), SZ_4K); busfreq_dev = &pdev->dev; @@ -335,6 +610,18 @@ 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); + } + + pll1 = clk_get(NULL, "pll1_main_clk"); + if (IS_ERR(pll1)) { + printk(KERN_DEBUG "%s: failed to get pll1\n", __func__); + return PTR_ERR(pll1); + } + pll2 = clk_get(NULL, "pll2"); if (IS_ERR(pll2)) { printk(KERN_DEBUG "%s: failed to get pll2\n", __func__); @@ -347,6 +634,14 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(pll3); } + if (cpu_is_mx53()) { + pll4 = clk_get(NULL, "pll4"); + if (IS_ERR(pll4)) { + printk(KERN_DEBUG "%s: failed to get pll4\n", __func__); + return PTR_ERR(pll4); + } + } + axi_a_clk = clk_get(NULL, "axi_a_clk"); if (IS_ERR(axi_a_clk)) { printk(KERN_DEBUG "%s: failed to get axi_a_clk\n", @@ -361,25 +656,19 @@ 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 (IS_ERR(ddr_hf_clk)) { - printk(KERN_DEBUG "%s: failed to get ddr_hf_clk\n", + ddr_clk = clk_get(NULL, "ddr_clk"); + if (IS_ERR(ddr_clk)) { + printk(KERN_DEBUG "%s: failed to get ddr_clk\n", __func__); - return PTR_ERR(ddr_hf_clk); + return PTR_ERR(ddr_clk); } - emi_slow_clk = clk_get(NULL, "emi_slow_clk"); - if (IS_ERR(emi_slow_clk)) { - printk(KERN_DEBUG "%s: failed to get emi_slow_clk\n", - __func__); - return PTR_ERR(emi_slow_clk); - } + ddr_hf_clk = clk_get_parent(ddr_clk); - nfc_clk = clk_get(NULL, "nfc_clk"); - if (IS_ERR(nfc_clk)) { - printk(KERN_DEBUG "%s: failed to get nfc_clk\n", + if (IS_ERR(ddr_hf_clk)) { + printk(KERN_DEBUG "%s: failed to get ddr_hf_clk\n", __func__); - return PTR_ERR(nfc_clk); + return PTR_ERR(ddr_hf_clk); } ahb_clk = clk_get(NULL, "ahb_clk"); @@ -389,20 +678,6 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(ahb_clk); } - vpu_core_clk = clk_get(NULL, "vpu_core_clk"); - if (IS_ERR(vpu_core_clk)) { - printk(KERN_DEBUG "%s: failed to get vpu_core_clk\n", - __func__); - return PTR_ERR(vpu_core_clk); - } - - ddr_clk = clk_get(NULL, "ddr_clk"); - if (IS_ERR(ddr_clk)) { - printk(KERN_DEBUG "%s: failed to get ddr_clk\n", - __func__); - return PTR_ERR(ddr_clk); - } - cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_DEBUG "%s: failed to get cpu_clk\n", @@ -410,35 +685,25 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return PTR_ERR(cpu_clk); } - ipu_clk = clk_get(NULL, "ipu_clk"); - if (IS_ERR(ipu_clk)) { - printk(KERN_DEBUG "%s: failed to get ipu_clk\n", - __func__); - return PTR_ERR(ipu_clk); - } - if (cpu_is_mx51()) emi_garb_clk = clk_get(NULL, "emi_garb_clk"); - else + else if (cpu_is_mx53()) emi_garb_clk = clk_get(NULL, "emi_intr_clk.1"); + else + emi_garb_clk = clk_get(NULL, "ocram_clk"); if (IS_ERR(emi_garb_clk)) { printk(KERN_DEBUG "%s: failed to get emi_garb_clk\n", __func__); return PTR_ERR(emi_garb_clk); } - vpu_clk = clk_get(NULL, "vpu_clk"); - if (IS_ERR(vpu_clk)) { - printk(KERN_DEBUG "%s: failed to get vpu_clk\n", - __func__); - return PTR_ERR(vpu_clk); - } - - periph_apm_clk = clk_get(NULL, "periph_apm_clk"); - if (IS_ERR(periph_apm_clk)) { - printk(KERN_DEBUG "%s: failed to get periph_apm_clk\n", - __func__); - return PTR_ERR(periph_apm_clk); + if (cpu_is_mx51() || cpu_is_mx53()) { + periph_apm_clk = clk_get(NULL, "periph_apm_clk"); + if (IS_ERR(periph_apm_clk)) { + printk(KERN_DEBUG "%s: failed to get periph_apm_clk\n", + __func__); + return PTR_ERR(periph_apm_clk); + } } lp_apm = clk_get(NULL, "lp_apm"); @@ -467,6 +732,49 @@ static int __devinit busfreq_probe(struct platform_device *pdev) return err; } + 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; + if (cpu_is_mx53()) { + ddr_normal_rate = pll2_rate / 1; + ddr_low_rate = pll2_rate / 3; + } else if (cpu_is_mx50()) { + ddr_normal_rate = clk_get_rate(ddr_clk); + ddr_low_rate = LP_APM_CLK; + } + } + if (cpu_is_mx50()) { + iram_alloc(SZ_8K, &iram_paddr); + /* Need to remap the area here since we want the memory region + to be executable. */ + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr, + SZ_8K, MT_HIGH_VECTORS); + memcpy(ddr_freq_change_iram_base, mx50_ddr_freq_change, SZ_8K); + change_ddr_freq = (void *)ddr_freq_change_iram_base; + + lp_regulator = regulator_get(NULL, "SW2"); + if (IS_ERR(lp_regulator)) { + printk(KERN_DEBUG + "%s: failed to get lp regulator\n", __func__); + return PTR_ERR(lp_regulator); + } + } cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); low_bus_freq_mode = 0; high_bus_freq_mode = 1; diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c index 7c6f614bf97f..5ec89a6570cd 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[]; @@ -394,7 +405,12 @@ static int _clk_pll_enable(struct clk *clk) struct timespec curtime; pllbase = _get_pll_base(clk); - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); + + if (reg & MXC_PLL_DP_CTL_UPEN) + return 0; + + reg |= MXC_PLL_DP_CTL_UPEN; __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); /* Wait for lock */ @@ -738,10 +754,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 +795,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 +907,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 +985,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 +1021,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 +1039,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 +1126,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 +1199,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 +1370,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 +1386,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 +1416,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 +1507,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 +1562,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 +1578,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 +1621,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 +2253,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 +2482,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 +2775,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 +3375,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 +3932,6 @@ static struct clk pgc_clk = { }; /*usb OTG clock */ - static struct clk usb_clk = { .name = "usb_clk", .rate = 60000000, @@ -3716,7 +3967,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 +4048,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 +4058,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 +4253,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 +4287,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 +4356,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 +4433,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 +4452,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 +4506,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 +4643,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 +4658,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 +4667,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 +4686,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; } @@ -4493,15 +4742,15 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long 1 << MXC_CCM_CCGR5_CG6_OFFSET | 3 << MXC_CCM_CCGR5_CG7_OFFSET | 1 << MXC_CCM_CCGR5_CG8_OFFSET | - 3 << MXC_CCM_CCGR5_CG9_OFFSET | + 1 << MXC_CCM_CCGR5_CG9_OFFSET | 1 << MXC_CCM_CCGR5_CG10_OFFSET | 3 << MXC_CCM_CCGR5_CG11_OFFSET, MXC_CCM_CCGR5); - __raw_writel(3 << MXC_CCM_CCGR6_CG0_OFFSET | + __raw_writel(1 << 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 | + 1 << MXC_CCM_CCGR6_CG4_OFFSET | + 1 << MXC_CCM_CCGR6_CG8_OFFSET | + 1 << MXC_CCM_CCGR6_CG9_OFFSET | 3 << MXC_CCM_CCGR6_CG12_OFFSET | 3 << MXC_CCM_CCGR6_CG13_OFFSET , MXC_CCM_CCGR6); @@ -4544,7 +4793,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 +4802,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 +4837,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 +4849,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 +4862,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 +5055,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 +5083,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/cpu.c b/arch/arm/mach-mx5/cpu.c index 692d258a4a0c..44440569f041 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -19,6 +19,7 @@ * @ingroup MSL_MX51 */ +#include <linux/proc_fs.h> #include <linux/types.h> #include <linux/err.h> #include <linux/kernel.h> @@ -28,10 +29,29 @@ #include <linux/clk.h> #include <mach/common.h> #include <mach/hardware.h> -#include "crm_regs.h" +#include <asm/mach/map.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; +void __iomem *ccm_base; +void __iomem *databahn_base; +void *wait_in_iram_base; +void (*wait_in_iram)(void *ccm_addr, void *databahn_addr); + +extern void mx50_wait(u32 ccm_base, u32 databahn_addr); + +struct cpu_wp *(*get_cpu_wp)(int *wp); +void (*set_num_cpu_wp)(int num); static void __init mipi_hsc_disable(void) { @@ -54,7 +74,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 +123,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 +138,30 @@ static int __init post_cpu_init(void) } gpc_base = ioremap(MX53_BASE_ADDR(GPC_BASE_ADDR), SZ_4K); + ccm_base = ioremap(MX53_BASE_ADDR(CCM_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,15 +181,53 @@ 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); + } + databahn_base = ioremap(MX50_DATABAHN_BASE_ADDR, SZ_16K); + + if (cpu_is_mx50()) { + struct clk *ddr_clk = clk_get(NULL, "ddr_clk"); + unsigned long iram_paddr; + + iram_alloc(SZ_4K, &iram_paddr); + /* Need to remap the area here since we want the memory region + to be executable. */ + wait_in_iram_base = __arm_ioremap(iram_paddr, + SZ_4K, MT_HIGH_VECTORS); + memcpy(wait_in_iram_base, mx50_wait, SZ_4K); + wait_in_iram = (void *)wait_in_iram_base; + + clk_enable(ddr_clk); + + /* Set the DDR to enter automatic self-refresh. */ + /* Set the DDR to automatically enter lower power mode 4. */ + reg = __raw_readl(databahn_base + DATABAHN_CTL_REG22); + reg &= ~LOWPOWER_AUTOENABLE_MASK; + reg |= 1 << 1; + __raw_writel(reg, databahn_base + DATABAHN_CTL_REG22); + + /* set the counter for entering mode 4. */ + reg = __raw_readl(databahn_base + DATABAHN_CTL_REG21); + reg &= ~LOWPOWER_EXTERNAL_CNT_MASK; + reg = 128 << LOWPOWER_EXTERNAL_CNT_OFFSET; + __raw_writel(reg, databahn_base + DATABAHN_CTL_REG21); + + /* Enable low power mode 4 */ + reg = __raw_readl(databahn_base + DATABAHN_CTL_REG20); + reg &= ~LOWPOWER_CONTROL_MASK; + reg |= 1 << 1; + __raw_writel(reg, databahn_base + DATABAHN_CTL_REG20); + clk_disable(ddr_clk); + } return 0; } diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h index e53f55d258eb..b2660a34c0e9 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 @@ -80,6 +70,56 @@ extern void __iomem *pll4_base; #define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31) #define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF +/* Register addresses of apll and pfd*/ +#define MXC_ANADIG_FRAC0 0x10 +#define MXC_ANADIG_FRAC0_SET 0x14 +#define MXC_ANADIG_FRAC0_CLR 0x18 +#define MXC_ANADIG_FRAC1 0x20 +#define MXC_ANADIG_FRAC1_SET 0x24 +#define MXC_ANADIG_FRAC1_CLR 0x28 +#define MXC_ANADIG_MISC 0x60 +#define MXC_ANADIG_MISC_SET 0x64 +#define MXC_ANADIG_MISC_CLR 0x68 +#define MXC_ANADIG_PLLCTRL 0x70 +#define MXC_ANADIG_PLLCTRL_SET 0x74 +#define MXC_ANADIG_PLLCTRL_CLR 0x78 + +/* apll and pfd Register Bit definitions */ + +#define MXC_ANADIG_PFD3_CLKGATE (1 << 31) +#define MXC_ANADIG_PFD3_STABLE (1 << 30) +#define MXC_ANADIG_PFD3_FRAC_OFFSET 24 +#define MXC_ANADIG_PFD_FRAC_MASK 0x3F +#define MXC_ANADIG_PFD2_CLKGATE (1 << 23) +#define MXC_ANADIG_PFD2_STABLE (1 << 22) +#define MXC_ANADIG_PFD2_FRAC_OFFSET 16 +#define MXC_ANADIG_PFD1_CLKGATE (1 << 15) +#define MXC_ANADIG_PFD1_STABLE (1 << 14) +#define MXC_ANADIG_PFD1_FRAC_OFFSET 8 +#define MXC_ANADIG_PFD0_CLKGATE (1 << 7) +#define MXC_ANADIG_PFD0_STABLE (1 << 6) +#define MXC_ANADIG_PFD0_FRAC_OFFSET 0 + +#define MXC_ANADIG_PFD7_CLKGATE (1 << 31) +#define MXC_ANADIG_PFD7_STABLE (1 << 30) +#define MXC_ANADIG_PFD7_FRAC_OFFSET 24 +#define MXC_ANADIG_PFD6_CLKGATE (1 << 23) +#define MXC_ANADIG_PFD6_STABLE (1 << 22) +#define MXC_ANADIG_PFD6_FRAC_OFFSET 16 +#define MXC_ANADIG_PFD5_CLKGATE (1 << 15) +#define MXC_ANADIG_PFD5_STABLE (1 << 14) +#define MXC_ANADIG_PFD5_FRAC_OFFSET 8 +#define MXC_ANADIG_PFD4_CLKGATE (1 << 7) +#define MXC_ANADIG_PFD4_STABLE (1 << 6) +#define MXC_ANADIG_PFD4_FRAC_OFFSET 0 + +#define MXC_ANADIG_APLL_LOCK (1 << 31) +#define MXC_ANADIG_APLL_FORCE_LOCK (1 << 30) +#define MXC_ANADIG_PFD_DIS_OFFSET 16 +#define MXC_ANADIG_PFD_DIS_MASK 0xff +#define MXC_ANADIG_APLL_LOCK_CNT_OFFSET 0 +#define MXC_ANADIG_APLL_LOCK_CNT_MASK 0xffff + /* Register addresses of CCM*/ #define MXC_CCM_CCR (MXC_CCM_BASE + 0x00) #define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04) @@ -116,6 +156,22 @@ 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) + +/* CCM Register Offsets. */ +#define MXC_CCM_CDCR_OFFSET 0x4C +#define MXC_CCM_CACRR_OFFSET 0x10 +#define MXC_CCM_CDHIPR_OFFSET 0x48 /* Define the bits in register CCR */ #define MXC_CCM_CCR_COSC_EN (1 << 12) @@ -149,8 +205,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,12 +226,17 @@ 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) -#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27) +#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27) +#define MX50_CCM_CBCDR_WEIM_PODF_OFFSET (22) +#define MX50_CCM_CBCDR_WEIM_PODF_MASK (0x7 << 22) #define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22) #define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22) #define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19) @@ -209,6 +273,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 +294,12 @@ 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 MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_OFFSET (16) +#define MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_MASK (0x7 << 16) #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 +351,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 +511,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 +528,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 +548,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 +567,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 +577,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 +592,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 +621,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 +815,82 @@ 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_SYS */ +#define MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_OFFSET (30) +#define MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_OFFSET (28) +#define MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK (0x3 << 28) +#define MXC_CCM_CLK_SYS_DIV_XTAL_OFFSET (6) +#define MXC_CCM_CLK_SYS_DIV_XTAL_MASK (0xF << 6) +#define MXC_CCM_CLK_SYS_DIV_PLL_OFFSET (0) +#define MXC_CCM_CLK_SYS_DIV_PLL_MASK (0x3F) + + +/* 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 the bits in register GPMI */ +#define MXC_CCM_GPMI_CLKGATE_OFFSET (30) +#define MXC_CCM_GPMI_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_GPMI_CLK_DIV_OFFSET (0) +#define MXC_CCM_GPMI_CLK_DIV_MASK (0x3F) + +/* Define the bits in register BCH */ +#define MXC_CCM_BCH_CLKGATE_OFFSET (30) +#define MXC_CCM_BCH_CLKGATE_MASK (0x3 << 30) +#define MXC_CCM_BCH_CLK_DIV_OFFSET (0) +#define MXC_CCM_BCH_CLK_DIV_MASK (0x3F) + #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) @@ -787,11 +949,12 @@ extern void __iomem *arm_plat_base; #define MXC_DVFSPER_PMCR1 (MXC_DVFS_PER_BASE + 0x1C) /* GPC */ -#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0) -#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4) -#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8) -#define MXC_GPC_ALL_PU (MXC_GPC_BASE + 0xC) -#define MXC_GPC_NEON (MXC_GPC_BASE + 0x10) +#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0) +#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4) +#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8) +#define MXC_GPC_CNTR_OFFSET 0x0 +#define MXC_GPC_PGR_OFFSET 0x4 +#define MXC_GPC_VCR_OFFSET 0x8 /* PGC */ #define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 06f16db88993..09188c771c9d 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -17,17 +17,20 @@ #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> #include <linux/iram_alloc.h> +#include <linux/gpmi-nfc.h> #include <mach/common.h> #include <mach/hardware.h> #include <mach/gpio.h> #include <mach/sdma.h> -#include "crm_regs.h" #include "mx51_pins.h" #include "devices.h" +#include "dma-apbh.h" /* Flag used to indicate when IRAM has been initialized */ int iram_ready; @@ -95,6 +98,11 @@ struct platform_device mxc_keypad_device = { .resource = mxc_kpp_resources, }; +struct platform_device mxc_powerkey_device = { + .name = "mxcpwrkey", + .id = 0, +}; + static struct resource rtc_resources[] = { { .start = SRTC_BASE_ADDR, @@ -114,9 +122,80 @@ 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 gpmi_nfc_resources[] = { + { + .name = GPMI_NFC_GPMI_REGS_ADDR_RES_NAME, + .flags = IORESOURCE_MEM, + .start = GPMI_BASE_ADDR, + .end = GPMI_BASE_ADDR + SZ_8K - 1, + }, + { + .name = GPMI_NFC_GPMI_INTERRUPT_RES_NAME, + .flags = IORESOURCE_IRQ, + .start = MXC_INT_RAWNAND_GPMI, + .end = MXC_INT_RAWNAND_GPMI, + }, + { + .name = GPMI_NFC_BCH_REGS_ADDR_RES_NAME, + .flags = IORESOURCE_MEM, + .start = BCH_BASE_ADDR, + .end = BCH_BASE_ADDR + SZ_8K - 1, + }, + { + .name = GPMI_NFC_BCH_INTERRUPT_RES_NAME, + .flags = IORESOURCE_IRQ, + .start = MXC_INT_RAWNAND_BCH, + .end = MXC_INT_RAWNAND_BCH, + }, + { + .name = GPMI_NFC_DMA_CHANNELS_RES_NAME, + .flags = IORESOURCE_DMA, + .start = MXS_DMA_CHANNEL_AHB_APBH_GPMI0, + .end = MXS_DMA_CHANNEL_AHB_APBH_GPMI7, + }, + { + .name = GPMI_NFC_DMA_INTERRUPT_RES_NAME, + .flags = IORESOURCE_IRQ, + .start = MXC_INT_APBHDMA_CHAN0, + .end = MXC_INT_APBHDMA_CHAN7, + }, +}; + +struct platform_device gpmi_nfc_device = { + .name = GPMI_NFC_DRIVER_NAME, + .id = 0, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = gpmi_nfc_resources, + .num_resources = ARRAY_SIZE(gpmi_nfc_resources), }; static struct resource imx_nfc_resources[] = { @@ -213,6 +292,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 +355,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 +425,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[] = { @@ -307,6 +498,53 @@ struct platform_device mxcscc_device = { .resource = scc_resources, }; +static struct resource dcp_resources[] = { + + { + .flags = IORESOURCE_MEM, + .start = DCP_BASE_ADDR, + .end = DCP_BASE_ADDR + 0x2000 - 1, + }, { + .flags = IORESOURCE_IRQ, + .start = MXC_INT_DCP_CHAN0, + .end = MXC_INT_DCP_CHAN0, + }, { + .flags = IORESOURCE_IRQ, + .start = MXC_INT_DCP_CHAN1_3, + .end = MXC_INT_DCP_CHAN1_3, + }, +}; + +struct platform_device dcp_device = { + .name = "dcp", + .id = 0, + .num_resources = ARRAY_SIZE(dcp_resources), + .resource = dcp_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + + +static struct resource rngb_resources[] = { + { + .start = RNGB_BASE_ADDR, + .end = RNGB_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_RNGB_BLOCK, + .flags = IORESOURCE_IRQ, + }, +}; + +/* the RNGC driver applies for MX50's RNGB hw */ +struct platform_device mxc_rngb_device = { + .name = "fsl_rngc", + .id = 0, + .num_resources = ARRAY_SIZE(rngb_resources), + .resource = rngb_resources, +}; static struct resource mxc_fec_resources[] = { { @@ -508,6 +746,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 +881,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,9 +1063,58 @@ struct platform_device pata_fsl_device = { }, }; +/* On-Chip OTP device and resource */ +static struct resource otp_resource = { + .start = OCOTP_CTRL_BASE_ADDR, + .end = OCOTP_CTRL_BASE_ADDR + SZ_8K - 1, + .flags = IORESOURCE_MEM, +}; + +struct platform_device fsl_otp_device = { + .name = "ocotp", + .id = -1, + .resource = &otp_resource, + .num_resources = 1, +}; + +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[] = { +static struct resource usbotg_host_resources[] = { + { + .start = OTG_BASE_ADDR, + .end = OTG_BASE_ADDR + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_USB_OTG, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource usbotg_udc_resources[] = { { .start = OTG_BASE_ADDR, .end = OTG_BASE_ADDR + 0x1ff, @@ -836,8 +1145,8 @@ struct platform_device mxc_usbdr_udc_device = { .dma_mask = &usb_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, - .resource = usbotg_resources, - .num_resources = ARRAY_SIZE(usbotg_resources), + .resource = usbotg_udc_resources, + .num_resources = ARRAY_SIZE(usbotg_udc_resources), }; struct platform_device mxc_usbdr_otg_device = { @@ -854,8 +1163,8 @@ struct platform_device mxc_usbdr_otg_device = { struct platform_device mxc_usbdr_host_device = { .name = "fsl-ehci", .id = 0, - .num_resources = ARRAY_SIZE(usbotg_resources), - .resource = usbotg_resources, + .num_resources = ARRAY_SIZE(usbotg_host_resources), + .resource = usbotg_host_resources, .dev = { .dma_mask = &usb_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), @@ -970,23 +1279,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; + + 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); - return clk_enable(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 +1344,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 +1361,118 @@ 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, +}; + +static u64 pxp_dma_mask = DMA_BIT_MASK(32); +struct platform_device mxc_pxp_v4l2 = { + .name = "pxp-v4l2", + .id = -1, + .dev = { + .dma_mask = &pxp_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +struct platform_device mxc_v4l2_device = { + .name = "mxc_v4l2_capture", + .id = 0, +}; + +struct platform_device mxc_v4l2out_device = { + .name = "mxc_v4l2_output", + .id = 0, +}; + +struct resource viim_resources[] = { + [0] = { + .start = (GPT1_BASE_ADDR - 0x20000000), + .end = (GPT1_BASE_ADDR - 0x20000000) + PAGE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OCOTP_CTRL_BASE_ADDR, + .end = OCOTP_CTRL_BASE_ADDR + PAGE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; +struct platform_device mxs_viim = { + .name = "mxs_viim", + .id = -1, + .num_resources = ARRAY_SIZE(viim_resources), + .resource = viim_resources, +}; + +static struct resource dma_apbh_resources[] = { + { + .start = APBHDMA_BASE_ADDR, + .end = APBHDMA_BASE_ADDR + 0x2000 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device mxs_dma_apbh_device = { + .name = "mxs-dma-apbh", + .num_resources = ARRAY_SIZE(dma_apbh_resources), + .resource = dma_apbh_resources, +}; + +struct platform_device mxc_android_pmem_device = { + .name = "android_pmem", + .id = 0, +}; + +struct platform_device mxc_android_pmem_gpu_device = { + .name = "android_pmem", + .id = 1, +}; + +struct platform_device android_usb_device = { + .name = "android_usb", + .id = -1, +}; + void __init mx5_init_irq(void) { unsigned long tzic_addr; @@ -1049,7 +1481,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 +1698,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 +1719,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; @@ -1295,6 +1731,8 @@ int __init mxc_init_devices(void) scc_resources[0].end -= MX53_OFFSET; scc_resources[1].start = MX53_SCC_RAM_BASE_ADDR; scc_resources[1].end = MX53_SCC_RAM_BASE_ADDR + SZ_16K - 1; + rngb_resources[0].start -= MX53_OFFSET; + rngb_resources[0].end -= MX53_OFFSET; mxcspi1_resources[0].start -= MX53_OFFSET; mxcspi1_resources[0].end -= MX53_OFFSET; mxcspi2_resources[0].start -= MX53_OFFSET; @@ -1311,8 +1749,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; @@ -1331,8 +1773,10 @@ int __init mxc_init_devices(void) mxcsdhc2_resources[0].end -= MX53_OFFSET; mxcsdhc3_resources[0].start -= MX53_OFFSET; mxcsdhc3_resources[0].end -= MX53_OFFSET; - usbotg_resources[0].start -= MX53_OFFSET; - usbotg_resources[0].end -= MX53_OFFSET; + usbotg_host_resources[0].start -= MX53_OFFSET; + usbotg_host_resources[0].end -= MX53_OFFSET; + usbotg_udc_resources[0].start -= MX53_OFFSET; + usbotg_udc_resources[0].end -= MX53_OFFSET; usbotg_xcvr_resources[0].start -= MX53_OFFSET; usbotg_xcvr_resources[0].end -= MX53_OFFSET; usbh1_resources[0].start -= MX53_OFFSET; @@ -1341,19 +1785,40 @@ int __init mxc_init_devices(void) usbh2_resources[0].end -= MX53_OFFSET; mxc_gpu_resources[2].start = MX53_GPU2D_BASE_ADDR; mxc_gpu_resources[2].end = MX53_GPU2D_BASE_ADDR + SZ_4K - 1; - mxc_gpu_resources[4].start = MX53_GPU_GMEM_BASE_ADDR; - mxc_gpu_resources[4].end = MX53_GPU_GMEM_BASE_ADDR + SZ_256K - 1; mxc_gpu2d_resources[0].start = MX53_GPU2D_BASE_ADDR; mxc_gpu2d_resources[0].end = MX53_GPU2D_BASE_ADDR + SZ_4K - 1; + if (cpu_is_mx53()) { + mxc_gpu_resources[4].start = MX53_GPU_GMEM_BASE_ADDR; + mxc_gpu_resources[4].end = MX53_GPU_GMEM_BASE_ADDR + + SZ_256K - 1; + } else { + mxc_gpu_resources[1].start = 0; + mxc_gpu_resources[1].end = 0; + mxc_gpu_resources[3].start = 0; + mxc_gpu_resources[3].end = 0; + mxc_gpu_resources[4].start = 0; + mxc_gpu_resources[4].end = 0; + } 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..da6c6ac96428 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,7 +55,9 @@ 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 fsl_otp_device; extern struct platform_device gpu_device; extern struct platform_device mxc_fec_device; extern struct platform_device mxc_usbdr_udc_device; @@ -59,6 +65,25 @@ 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 mxc_pxp_v4l2; +extern struct platform_device epdc_device; +extern struct platform_device elcdif_device; +extern struct platform_device mxc_v4l2_device; +extern struct platform_device mxc_v4l2out_device; +extern struct platform_device mxs_viim; +extern struct platform_device mxs_dma_apbh_device; +extern struct platform_device gpmi_nfc_device; +extern struct platform_device mxc_rngb_device; +extern struct platform_device dcp_device; +extern struct platform_device mxc_android_pmem_device; +extern struct platform_device mxc_android_pmem_gpu_device; +extern struct platform_device android_usb_device; +extern struct platform_device mxc_powerkey_device; +extern struct platform_device ccwmx51js_keys_gpio; diff --git a/arch/arm/mach-mx5/devices_ccwmx51.c b/arch/arm/mach-mx5/devices_ccwmx51.c index 4e4a07f7c4a7..27eb3dc32064 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" @@ -52,6 +55,8 @@ #include "mx51_pins.h" #include "displays/displays.h" #include <linux/smc911x.h> +#include <linux/fec.h> +#include <linux/gpio_keys.h> #if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) #include <linux/mtd/mtd.h> @@ -60,65 +65,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 +234,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 +244,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 +318,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 +354,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 +443,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 +457,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 +470,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 +485,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); @@ -314,15 +523,11 @@ 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, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, + .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, + .gpc_vcr_offset = MXC_GPC_VCR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -356,6 +561,11 @@ struct mxc_dvfsper_data dvfs_per_data = { .lp_low = 1200000, }; +struct fec_platform_data fec_data = { + .phy = PHY_INTERFACE_MODE_MII, + .phy_mask = ~1UL, +}; + struct platform_pwm_backlight_data mxc_pwm_backlight_data = { .pwm_id = 0, .max_brightness = 255, @@ -364,90 +574,649 @@ 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 = IPU_PIX_FMT_RGB24, - .mode_str = "1024x768M-16@60", /* Default */ + .interface_pix_fmt = VIDEO_PIX_FMT, + .mode_str = "1024x768M-16@60", /* Default */ + }, + /* DISP1 */ + { + .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, -}; + +#if defined(CONFIG_KEYBOARD_GPIO) + +#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \ +{ \ + .gpio = gpio_num, \ + .type = ev_type, \ + .code = ev_code, \ + .active_low = act_low, \ + .desc = "btn " descr, \ +} + +#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \ + GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description) + +// user key 1 +#if defined(CONFIG_JSCCWMX51_V2) +#define USER_KEY2_GPIO_NR 70 +#else +#define USER_KEY2_GPIO_NR 8 #endif +// user key 2 +#define USER_KEY1_GPIO_NR 1 + +static struct gpio_keys_button ccwmx51js_gpio_keys[] = { + GPIO_BUTTON_LOW(USER_KEY1_GPIO_NR, KEY_MENU, "menu"), + GPIO_BUTTON_LOW(USER_KEY2_GPIO_NR, KEY_HOME, "home"), +}; + + +struct gpio_keys_platform_data ccwmx51js_gpio_key_info = { + .buttons = ccwmx51js_gpio_keys, + .nbuttons = ARRAY_SIZE(ccwmx51js_gpio_keys), +}; + +struct platform_device ccwmx51js_keys_gpio = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &ccwmx51js_gpio_key_info, + }, +}; +#endif // KEYBOARD_GPIO #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]; + +#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; + } -struct ccwmx51_lcd_pdata * ccwmx51_get_display(char *name) + 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) +{ + if (!(debug & AD9389_DBG)) + return; + if (vm == NULL) + return; + + 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" : ""); +} + +static void fb_dump_var(const char *str, struct fb_var_screeninfo *var) { - char *options = NULL, *p; + if (!(debug & AD9389_DBG)) + return; + if (var == 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 %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); +} - if (!options) - return -ENODEV; +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 (!strncasecmp(options, "VGA", 3)) { - pr_info("VGA interface is primary\n"); + 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 ((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 */ + } 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; + } + } + } + + 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..6e53be44a5f5 100644 --- a/arch/arm/mach-mx5/devices_ccwmx51.h +++ b/arch/arm/mach-mx5/devices_ccwmx51.h @@ -28,17 +28,29 @@ extern struct mxc_w1_config mxc_w1_data; extern struct mxc_spdif_platform_data mxc_spdif_data; extern struct tve_platform_data tve_data; extern struct mxc_dvfs_platform_data dvfs_core_data; +extern struct fec_platform_data fec_data; extern struct mxc_dvfsper_data dvfs_per_data; 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); +extern struct gpio_keys_platform_data ccwmx51js_gpio_key_info; +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/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/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..21d654298b54 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -16,6 +16,7 @@ #include <mach/hardware.h> #include <asm/pgtable.h> #include <asm/mach/map.h> +#include <mach/iomux-v3.h> /*! * @file mach-mx51/mm.c @@ -60,8 +61,9 @@ void __init mx5_map_io(void) { int i; + mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR)); /* 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/mx51_3stack.c b/arch/arm/mach-mx5/mx51_3stack.c index 7c3d80938777..cc5a205d594d 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); @@ -147,15 +184,77 @@ static struct mxc_vpu_platform_data mxc_vpu_data = { .reset = mx5_vpu_reset, }; -extern void mx51_babbage_gpio_spi_chipselect_active(int cspi_mode, int status, - int chipselect); -extern void mx51_babbage_gpio_spi_chipselect_inactive(int cspi_mode, int status, - int chipselect); +/* workaround for ecspi chipselect pin may not keep correct level when idle */ +static void mx51_3ds_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(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0, + PAD_CTL_HYS_ENABLE | + PAD_CTL_PKE_ENABLE | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST); + break; + case 0x2: + gpio = IOMUX_TO_GPIO(MX51_PIN_CSPI1_SS0); + mxc_request_iomux(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_GPIO); + gpio_request(gpio, "cspi1_ss0"); + gpio_direction_output(gpio, 0); + gpio_set_value(gpio, 1 & (~status)); + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + +static void mx51_3ds_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0); + mxc_request_iomux(MX51_PIN_CSPI1_SS0, + IOMUX_CONFIG_GPIO); + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO); + break; + case 0x2: + mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_GPIO); + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + static struct mxc_spi_master mxcspi1_data = { .maxchipselect = 4, .spi_version = 23, - .chipselect_active = mx51_babbage_gpio_spi_chipselect_active, - .chipselect_inactive = mx51_babbage_gpio_spi_chipselect_inactive, + .chipselect_active = mx51_3ds_gpio_spi_chipselect_active, + .chipselect_inactive = mx51_3ds_gpio_spi_chipselect_inactive, }; static struct mxc_i2c_platform_data mxci2c_data = { @@ -179,15 +278,11 @@ 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, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, + .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, + .gpc_vcr_offset = MXC_GPC_VCR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -685,30 +780,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, @@ -879,6 +950,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_ipu_data.csi_clk[0] = clk_get(NULL, "csi_mclk1"); + mxc_ipu_data.csi_clk[1] = clk_get(NULL, "csi_mclk2"); mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); clk_put(mxc_spdif_data.spdif_core_clk); @@ -909,8 +982,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 +1009,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, @@ -948,6 +1020,8 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data); mxc_register_device(&mxc_bt_device, &mxc_bt_data); mxc_register_device(&mxc_gps_device, &gps_data); + mxc_register_device(&mxc_v4l2_device, NULL); + mxc_register_device(&mxc_v4l2out_device, NULL); mx5_usb_dr_init(); mx5_usbh1_init(); diff --git a/arch/arm/mach-mx5/mx51_babbage.c b/arch/arm/mach-mx5/mx51_babbage.c index 4a962ab6f647..1acc44937e65 100644 --- a/arch/arm/mach-mx5/mx51_babbage.c +++ b/arch/arm/mach-mx5/mx51_babbage.c @@ -25,13 +25,13 @@ #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 <mach/common.h> #include <mach/hardware.h> #include <asm/setup.h> @@ -39,17 +39,21 @@ #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 <mach/iomux-mx51.h> +#include <mach/gpio.h> #include "devices.h" -#include "board-mx51_babbage.h" -#include "iomux.h" -#include "mx51_pins.h" #include "crm_regs.h" #include "usb.h" +#include <mach/mxc_edid.h> +#include <linux/android_pmem.h> +#include <linux/usb/android.h> +#include <linux/switch.h> /*! * @file mach-mx51/mx51_babbage.c @@ -58,11 +62,181 @@ * * @ingroup MSL_MX51 */ -extern void __init mx51_babbage_io_init(void); + +#define BABBAGE_SD1_CD (0*32 + 0) /* GPIO_1_0 */ +#define BABBAGE_SD1_WP (0*32 + 1) /* GPIO_1_1 */ +#define BABBAGE_SD2_CD_2_0 (0*32 + 4) /* GPIO_1_4 */ +#define BABBAGE_SD2_WP (0*32 + 5) /* GPIO_1_5 */ +#define BABBAGE_SD2_CD_2_5 (0*32 + 6) /* GPIO_1_6 */ +#define BABBAGE_USBH1_HUB_RST (0*32 + 7) /* GPIO_1_7 */ +#define BABBAGE_PMIC_INT (0*32 + 8) /* GPIO_1_8 */ + +#define BABBAGE_USB_CLK_EN_B (1*32 + 1) /* GPIO_2_1 */ +#define BABBAGE_OSC_EN_B (1*32 + 2) /* GPIO_2_2 */ +#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */ +#define BABBAGE_CAM_RESET (1*32 + 7) /* GPIO_2_7 */ +#define BABBAGE_FM_PWR (1*32 + 12) /* GPIO_2_12 */ +#define BABBAGE_VGA_RESET (1*32 + 13) /* GPIO_2_13 */ +#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */ +#define BABBAGE_FM_RESET (1*32 + 15) /* GPIO_2_15 */ +#define BABBAGE_AUDAMP_STBY (1*32 + 17) /* GPIO_2_17 */ +#define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */ + +#define BABBAGE_26M_OSC_EN (2*32 + 1) /* GPIO_3_1 */ +#define BABBAGE_LVDS_POWER_DOWN (2*32 + 3) /* GPIO_3_3 */ +#define BABBAGE_DISP_BRIGHTNESS_CTL (2*32 + 4) /* GPIO_3_4 */ +#define BABBAGE_DVI_RESET (2*32 + 5) /* GPIO_3_5 */ +#define BABBAGE_DVI_POWER (2*32 + 6) /* GPIO_3_6 */ +#define BABBAGE_HEADPHONE_DET (2*32 + 26) /* GPIO_3_26 */ +#define BABBAGE_DVI_DET (2*32 + 28) /* GPIO_3_28 */ + +#define BABBAGE_LCD_3V3_ON (3*32 + 9) /* GPIO_4_9 */ +#define BABBAGE_LCD_5V_ON (3*32 + 10) /* GPIO_4_10 */ +#define BABBAGE_CAM_LOW_POWER (3*32 + 10) /* GPIO_4_12 */ +#define BABBAGE_DVI_I2C_EN (3*32 + 14) /* GPIO_4_14 */ +#define BABBAGE_CSP1_SS0_GPIO (3*32 + 24) /* GPIO_4_24 */ +#define BABBAGE_AUDIO_CLK_EN (3*32 + 26) /* GPIO_4_26 */ + +extern int __init mx51_babbage_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; +static struct pad_desc mx51babbage_pads[] = { + /* UART1 */ + MX51_PAD_UART1_RXD__UART1_RXD, + MX51_PAD_UART1_TXD__UART1_TXD, + MX51_PAD_UART1_RTS__UART1_RTS, + MX51_PAD_UART1_CTS__UART1_CTS, + + /* USB HOST1 */ + MX51_PAD_USBH1_STP__USBH1_STP, + MX51_PAD_USBH1_CLK__USBH1_CLK, + MX51_PAD_USBH1_DIR__USBH1_DIR, + MX51_PAD_USBH1_NXT__USBH1_NXT, + MX51_PAD_USBH1_DATA0__USBH1_DATA0, + MX51_PAD_USBH1_DATA1__USBH1_DATA1, + MX51_PAD_USBH1_DATA2__USBH1_DATA2, + MX51_PAD_USBH1_DATA3__USBH1_DATA3, + MX51_PAD_USBH1_DATA4__USBH1_DATA4, + MX51_PAD_USBH1_DATA5__USBH1_DATA5, + MX51_PAD_USBH1_DATA6__USBH1_DATA6, + MX51_PAD_USBH1_DATA7__USBH1_DATA7, + + MX51_PAD_GPIO_1_0__GPIO_1_0, + MX51_PAD_GPIO_1_1__GPIO_1_1, + MX51_PAD_GPIO_1_4__GPIO_1_4, + MX51_PAD_GPIO_1_5__GPIO_1_5, + MX51_PAD_GPIO_1_6__GPIO_1_6, + MX51_PAD_GPIO_1_7__GPIO_1_7, + MX51_PAD_GPIO_1_8__GPIO_1_8, + MX51_PAD_UART3_RXD__GPIO_1_22, + + MX51_PAD_EIM_D17__GPIO_2_1, + MX51_PAD_EIM_D18__GPIO_2_2, + MX51_PAD_EIM_D21__GPIO_2_5, + MX51_PAD_EIM_D23__GPIO_2_7, + MX51_PAD_EIM_A16__GPIO_2_10, + MX51_PAD_EIM_A17__GPIO_2_11, + MX51_PAD_EIM_A18__GPIO_2_12, + MX51_PAD_EIM_A19__GPIO_2_13, + MX51_PAD_EIM_A20__GPIO_2_14, + MX51_PAD_EIM_A21__GPIO_2_15, + MX51_PAD_EIM_A22__GPIO_2_16, + MX51_PAD_EIM_A23__GPIO_2_17, + MX51_PAD_EIM_A27__GPIO_2_21, + MX51_PAD_EIM_DTACK__GPIO_2_31, + + MX51_PAD_EIM_LBA__GPIO_3_1, + MX51_PAD_DI1_D0_CS__GPIO_3_3, + MX51_PAD_DISPB2_SER_DIN__GPIO_3_5, + MX51_PAD_DISPB2_SER_DIO__GPIO_3_6, + MX51_PAD_NANDF_CS0__GPIO_3_16, + MX51_PAD_NANDF_CS1__GPIO_3_17, + MX51_PAD_NANDF_D14__GPIO_3_26, + MX51_PAD_NANDF_D12__GPIO_3_28, + + MX51_PAD_CSI2_D12__GPIO_4_9, + MX51_PAD_CSI2_D13__GPIO_4_10, + MX51_PAD_CSI2_D19__GPIO_4_12, + MX51_PAD_CSI2_HSYNC__GPIO_4_14, + MX51_PAD_CSPI1_RDY__GPIO_4_26, + + MX51_PAD_EIM_EB2__FEC_MDIO, + MX51_PAD_EIM_EB3__FEC_RDAT1, + MX51_PAD_EIM_CS2__FEC_RDAT2, + MX51_PAD_EIM_CS3__FEC_RDAT3, + MX51_PAD_EIM_CS4__FEC_RX_ER, + MX51_PAD_EIM_CS5__FEC_CRS, + MX51_PAD_NANDF_RB2__FEC_COL, + MX51_PAD_NANDF_RB3__FEC_RXCLK, + MX51_PAD_NANDF_RB6__FEC_RDAT0, + MX51_PAD_NANDF_RB7__FEC_TDAT0, + MX51_PAD_NANDF_CS2__FEC_TX_ER, + MX51_PAD_NANDF_CS3__FEC_MDC, + MX51_PAD_NANDF_CS4__FEC_TDAT1, + MX51_PAD_NANDF_CS5__FEC_TDAT2, + MX51_PAD_NANDF_CS6__FEC_TDAT3, + MX51_PAD_NANDF_CS7__FEC_TX_EN, + MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK, + + MX51_PAD_GPIO_NAND__PATA_INTRQ, + + MX51_PAD_DI_GP4__DI2_PIN15, +#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL + MX51_PAD_DISP1_DAT22__DISP2_DAT16, + MX51_PAD_DISP1_DAT23__DISP2_DAT17, + + MX51_PAD_DI1_D1_CS__GPIO_3_4, +#endif + MX51_PAD_I2C1_CLK__HSI2C_CLK, + MX51_PAD_I2C1_DAT__HSI2C_DAT, + MX51_PAD_EIM_D16__I2C1_SDA, + MX51_PAD_EIM_D19__I2C1_SCL, + + MX51_PAD_GPIO_1_2__PWM_PWMO, + + MX51_PAD_KEY_COL5__I2C2_SDA, + MX51_PAD_KEY_COL4__I2C2_SCL, + + MX51_PAD_SD1_CMD__SD1_CMD, + MX51_PAD_SD1_CLK__SD1_CLK, + MX51_PAD_SD1_DATA0__SD1_DATA0, + MX51_PAD_SD1_DATA1__SD1_DATA1, + MX51_PAD_SD1_DATA2__SD1_DATA2, + MX51_PAD_SD1_DATA3__SD1_DATA3, + + MX51_PAD_SD2_CMD__SD2_CMD, + MX51_PAD_SD2_CLK__SD2_CLK, + MX51_PAD_SD2_DATA0__SD2_DATA0, + MX51_PAD_SD2_DATA1__SD2_DATA1, + MX51_PAD_SD2_DATA2__SD2_DATA2, + MX51_PAD_SD2_DATA3__SD2_DATA3, + + MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD, + MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD, + MX51_PAD_AUD3_BB_CK__AUD3_BB_CK, + MX51_PAD_AUD3_BB_FS__AUD3_BB_FS, + + MX51_PAD_CSPI1_SS1__CSPI1_SS1, + + MX51_PAD_DI_GP3__CSI1_DATA_EN, + MX51_PAD_CSI1_D10__CSI1_D10, + MX51_PAD_CSI1_D11__CSI1_D11, + MX51_PAD_CSI1_D12__CSI1_D12, + MX51_PAD_CSI1_D13__CSI1_D13, + MX51_PAD_CSI1_D14__CSI1_D14, + MX51_PAD_CSI1_D15__CSI1_D15, + MX51_PAD_CSI1_D16__CSI1_D16, + MX51_PAD_CSI1_D17__CSI1_D17, + MX51_PAD_CSI1_D18__CSI1_D18, + MX51_PAD_CSI1_D19__CSI1_D19, + MX51_PAD_CSI1_VSYNC__CSI1_VSYNC, + MX51_PAD_CSI1_HSYNC__CSI1_HSYNC, + + MX51_PAD_OWIRE_LINE__SPDIF_OUT1, +}; + /* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */ static struct cpu_wp cpu_wp_auto[] = { { @@ -96,6 +270,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, @@ -106,7 +298,7 @@ static struct fb_videomode video_modes[] = { FB_VMODE_NONINTERLACED, 0,}, { - /* MITSUBISHI LVDS panel */ + /*MITSUBISHI LVDS panel */ "XGA", 60, 1024, 768, 15385, 220, 40, 21, 7, @@ -114,6 +306,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) @@ -166,10 +364,73 @@ static struct mxc_vpu_platform_data mxc_vpu_data = { .reset = mx5_vpu_reset, }; -extern void mx51_babbage_gpio_spi_chipselect_active(int cspi_mode, int status, - int chipselect); -extern void mx51_babbage_gpio_spi_chipselect_inactive(int cspi_mode, int status, - int chipselect); +static struct fec_platform_data fec_data = { + .phy = PHY_INTERFACE_MODE_MII, + .phy_mask = ~1UL, +}; + +/* workaround for ecspi chipselect pin may not keep correct level when idle */ +static void mx51_babbage_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + { + struct pad_desc cspi1_ss0 = MX51_PAD_CSPI1_SS0__CSPI1_SS0; + + mxc_iomux_v3_setup_pad(&cspi1_ss0); + break; + } + case 0x2: + { + struct pad_desc cspi1_ss0_gpio = MX51_PAD_CSPI1_SS0__GPIO_4_24; + + mxc_iomux_v3_setup_pad(&cspi1_ss0_gpio); + gpio_request(BABBAGE_CSP1_SS0_GPIO, "cspi1-gpio"); + gpio_direction_output(BABBAGE_CSP1_SS0_GPIO, 0); + gpio_set_value(BABBAGE_CSP1_SS0_GPIO, 1 & (~status)); + break; + } + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + +static void mx51_babbage_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + break; + case 0x2: + gpio_free(BABBAGE_CSP1_SS0_GPIO); + break; + + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + static struct mxc_spi_master mxcspi1_data = { .maxchipselect = 4, .spi_version = 23, @@ -197,15 +458,11 @@ 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, - .dvfs_thrs_reg_addr = MXC_DVFSTHRS, - .dvfs_coun_reg_addr = MXC_DVFSCOUN, - .dvfs_emac_reg_addr = MXC_DVFSEMAC, - .dvfs_cntr_reg_addr = MXC_DVFSCNTR, + .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET, + .gpc_vcr_offset = MXC_GPC_VCR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, .prediv_mask = 0x1F800, .prediv_offset = 11, .prediv_val = 3, @@ -258,30 +515,73 @@ 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) { - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DI1_D1_CS), 1); -} + if (!machine_is_mx51_babbage()) + return 0; -static struct mxc_lcd_platform_data lcd_wvga_data = { - .reset = wvga_reset, -}; + /* DI0-LVDS */ + gpio_set_value(BABBAGE_LVDS_POWER_DOWN, 0); + msleep(1); + gpio_set_value(BABBAGE_LVDS_POWER_DOWN, 1); + gpio_set_value(BABBAGE_LCD_3V3_ON, 1); + gpio_set_value(BABBAGE_LCD_5V_ON, 1); -static struct platform_device lcd_wvga_device = { - .name = "lcd_claa", -}; + /* DVI Detect */ + gpio_request(BABBAGE_DVI_DET, "dvi-detect"); + gpio_direction_input(BABBAGE_DVI_DET); + /* DVI Reset - Assert for i2c disabled mode */ + gpio_request(BABBAGE_DVI_RESET, "dvi-reset"); + gpio_direction_output(BABBAGE_DVI_RESET, 0); + /* DVI Power-down */ + gpio_request(BABBAGE_DVI_POWER, "dvi-power"); + gpio_direction_output(BABBAGE_DVI_POWER, 1); + + /* WVGA Reset */ + gpio_set_value(BABBAGE_DISP_BRIGHTNESS_CTL, 1); + + 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]); + + /* 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,171 +670,17 @@ 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); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); + gpio_direction_output(BABBAGE_DVI_RESET, 0); + gpio_set_value(BABBAGE_DVI_RESET, 0); msleep(50); /* do reset */ - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 1); + gpio_set_value(BABBAGE_DVI_RESET, 1); msleep(20); /* tRES >= 50us */ - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_DISPB2_SER_DIN), 0); + gpio_set_value(BABBAGE_DVI_RESET, 0); } static struct mxc_lcd_platform_data dvi_data = { @@ -545,14 +691,13 @@ static struct mxc_lcd_platform_data dvi_data = { static void vga_reset(void) { - gpio_request(IOMUX_TO_GPIO(MX51_PIN_EIM_A19), "eim_a19"); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A19), 0); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A19), 0); + + gpio_set_value(BABBAGE_VGA_RESET, 0); msleep(50); /* do reset */ - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A19), 1); + gpio_set_value(BABBAGE_VGA_RESET, 1); msleep(10); /* tRES >= 50us */ - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A19), 0); + gpio_set_value(BABBAGE_VGA_RESET, 0); } static struct mxc_lcd_platform_data vga_data = { @@ -565,22 +710,23 @@ static struct mxc_lcd_platform_data vga_data = { static void si4702_reset(void) { return; - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A21), 0); + + gpio_set_value(BABBAGE_FM_RESET, 0); msleep(100); - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A21), 1); + gpio_set_value(BABBAGE_FM_RESET, 1); msleep(100); } static void si4702_clock_ctl(int flag) { - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A18), flag); + gpio_set_value(BABBAGE_FM_PWR, flag); msleep(100); } static void si4702_gpio_get(void) { - gpio_request(IOMUX_TO_GPIO(MX51_PIN_EIM_A18), "eim_a18"); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A18), 0); + gpio_request(BABBAGE_FM_PWR, "fm-power"); + gpio_direction_output(BABBAGE_FM_PWR, 0); } static void si4702_gpio_put(void) @@ -706,9 +852,9 @@ 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(MX51_PIN_GPIO1_1)); + rc = gpio_get_value(BABBAGE_SD1_WP); else - rc = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5)); + rc = gpio_get_value(BABBAGE_SD2_WP); return rc; } @@ -718,25 +864,26 @@ 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(MX51_PIN_GPIO1_0)); + ret = gpio_get_value(BABBAGE_SD1_CD); return ret; } else { /* config the det pin for SDHC2 */ if (board_is_rev(BOARD_REV_2)) /* BB2.5 */ - ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_6)); + ret = gpio_get_value(BABBAGE_SD2_CD_2_5); else /* BB2.0 */ - ret = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_4)); + ret = gpio_get_value(BABBAGE_SD2_CD_2_0); return ret; } } 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", @@ -753,27 +900,25 @@ static struct mxc_mmc_platform_data mmc2_data = { .status = sdhc_get_card_det_status, .wp_status = sdhc_write_protect, .clock_mmc = "esdhc_clk", + .clk_always_on = 1, }; static int mxc_sgtl5000_amp_enable(int enable) { - gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A23), enable ? 1 : 0); + gpio_set_value(BABBAGE_AUDAMP_STBY, enable ? 1 : 0); return 0; } static int headphone_det_status(void) { - if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) - return (gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_NANDF_D14)) == 0); - - return gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_NANDF_CS0)); + return (gpio_get_value(BABBAGE_HEADPHONE_DET) == 0); } static struct mxc_audio_platform_data sgtl5000_data = { .ssi_num = 1, .src_port = 2, .ext_port = 3, - .hp_irq = IOMUX_TO_IRQ(MX51_PIN_NANDF_D14), + .hp_irq = IOMUX_TO_IRQ_V3(BABBAGE_HEADPHONE_DET), .hp_status = headphone_det_status, .amp_enable = mxc_sgtl5000_amp_enable, .sysclk = 12288000, @@ -783,6 +928,41 @@ static struct platform_device mxc_sgtl5000_device = { .name = "imx-3stack-sgtl5000", }; +static int __initdata enable_w1 = { 0 }; +static int __init w1_setup(char *__unused) +{ + enable_w1 = 1; + return cpu_is_mx51(); +} + +__setup("w1", w1_setup); + +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem_adsp", + .start = 0, + .size = SZ_32M, + .no_allocator = 0, + .cached = PMEM_NONCACHE_NORMAL, +}; + +static struct android_pmem_platform_data android_pmem_gpu_pdata = { + .name = "pmem_gpu", + .start = 0, + .size = SZ_32M, + .no_allocator = 0, + .cached = PMEM_CACHE_ENABLE, +}; + +static struct android_usb_platform_data android_usb_pdata = { + .vendor_id = 0x0bb4, + .product_id = 0x0c01, + .adb_product_id = 0x0c02, + .version = 0x0100, + .product_name = "Android Phone", + .manufacturer_name = "Freescale", + .nluns = 3, +}; + /*! * 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 @@ -804,12 +984,32 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, int left_mem = 0; int gpu_mem = SZ_64M; int fb_mem = SZ_32M; + int size; mxc_set_cpu_type(MXC_CPU_MX51); get_cpu_wp = mx51_babbage_get_cpu_wp; set_num_cpu_wp = mx51_babbage_set_num_cpu_wp; + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_MEM) + continue; + size = t->u.mem.size; + + android_pmem_pdata.start = + PHYS_OFFSET + size - android_pmem_pdata.size; + android_pmem_gpu_pdata.start = + android_pmem_pdata.start - android_pmem_gpu_pdata.size; + gpu_device.resource[5].start = + android_pmem_gpu_pdata.start - SZ_16M; + gpu_device.resource[5].end = + gpu_device.resource[5].start + SZ_16M - 1; + size -= android_pmem_pdata.size; + size -= android_pmem_gpu_pdata.size; + size -= SZ_16M; + t->u.mem.size = size; + } +#if 0 for_each_tag(mem_tag, tags) { if (mem_tag->hdr.tag == ATAG_MEM) { total_mem = mem_tag->u.mem.size; @@ -866,7 +1066,82 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, } #endif } +#endif +} + +static struct switch_dev dvi_sdev; +static int state; +static struct delayed_work dvi_det_work; +static void dvi_update_detect_status(void) +{ + int level; + + level = gpio_get_value(BABBAGE_DVI_DET); + if (level == 1) { + pr_info(KERN_INFO "DVI device plug-in\n"); + state = 1; + } else { + pr_info(KERN_INFO "DVI device plug-out\n"); + state = 0; + } + switch_set_state(&dvi_sdev, state); +} + +static void dvi_work_func(struct work_struct *work) +{ + dvi_update_detect_status(); +} + +static irqreturn_t dvi_det_int(int irq, void *dev_id) +{ + schedule_delayed_work(&dvi_det_work, msecs_to_jiffies(10)); + return 0; +} + +static ssize_t print_switch_name(struct switch_dev *sdev, char *buf) +{ + return sprintf(buf, "dvi_det\n"); +} + +static ssize_t print_switch_state(struct switch_dev *sdev, char *buf) +{ + return sprintf(buf, "%s\n", (state ? "online" : "offline")); +} + +static int __init mxc_init_dvi_det(void) +{ + int irq, level, ret; + + if (!machine_is_mx51_babbage()) + return 0; + + dvi_sdev.name = "dvi_det"; + dvi_sdev.print_name = print_switch_name; + dvi_sdev.print_state = print_switch_state; + switch_dev_register(&dvi_sdev); + + level = gpio_get_value(BABBAGE_DVI_DET); + if (level == 1) { + pr_info(KERN_INFO "DVI device plug-in\n"); + state = 1; + } else { + pr_info(KERN_INFO "DVI device plug-out\n"); + state = 0; + } + + INIT_DELAYED_WORK(&dvi_det_work, dvi_work_func); + + irq = IOMUX_TO_IRQ_V3(BABBAGE_DVI_DET); + set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); + ret = request_irq(irq, dvi_det_int, 0, "dvi_det", 0); + if (ret) { + pr_info("register DVI detect interrupt failed\n"); + return -1; + } + return 0; } +late_initcall(mxc_init_dvi_det); + #define PWGT1SPIEN (1<<15) #define PWGT2SPIEN (1<<16) @@ -899,7 +1174,7 @@ static int __init mxc_init_power_key(void) { /* Set power key as wakeup resource */ int irq, ret; - irq = IOMUX_TO_IRQ(MX51_PIN_EIM_A27); + irq = IOMUX_TO_IRQ_V3(BABBAGE_POWER_KEY); set_irq_type(irq, IRQF_TRIGGER_RISING); ret = request_irq(irq, power_key_int, 0, "power_key", 0); if (ret) @@ -910,6 +1185,113 @@ static int __init mxc_init_power_key(void) } late_initcall(mxc_init_power_key); +static void __init mx51_babbage_io_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, + ARRAY_SIZE(mx51babbage_pads)); + + gpio_request(BABBAGE_PMIC_INT, "pmic-int"); + gpio_request(BABBAGE_SD1_CD, "sdhc1-detect"); + gpio_request(BABBAGE_SD1_WP, "sdhc1-wp"); + + gpio_direction_input(BABBAGE_PMIC_INT); + gpio_direction_input(BABBAGE_SD1_CD); + gpio_direction_input(BABBAGE_SD1_WP); + + if (board_is_rev(BOARD_REV_2)) { + /* SD2 CD for BB2.5 */ + gpio_request(BABBAGE_SD2_CD_2_5, "sdhc2-detect"); + gpio_direction_input(BABBAGE_SD2_CD_2_5); + } else { + /* SD2 CD for BB2.0 */ + gpio_request(BABBAGE_SD2_CD_2_0, "sdhc2-detect"); + gpio_direction_input(BABBAGE_SD2_CD_2_0); + } + gpio_request(BABBAGE_SD2_WP, "sdhc2-wp"); + gpio_direction_input(BABBAGE_SD2_WP); + + /* reset usbh1 hub */ + gpio_request(BABBAGE_USBH1_HUB_RST, "hub-rst"); + gpio_direction_output(BABBAGE_USBH1_HUB_RST, 0); + gpio_set_value(BABBAGE_USBH1_HUB_RST, 0); + msleep(1); + gpio_set_value(BABBAGE_USBH1_HUB_RST, 1); + + /* reset FEC PHY */ + gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset"); + gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0); + msleep(10); + gpio_set_value(BABBAGE_FEC_PHY_RESET, 1); + + /* reset FM */ + gpio_request(BABBAGE_FM_RESET, "fm-reset"); + gpio_direction_output(BABBAGE_FM_RESET, 0); + msleep(10); + gpio_set_value(BABBAGE_FM_RESET, 1); + + /* Drive 26M_OSC_EN line high */ + gpio_request(BABBAGE_26M_OSC_EN, "26m-osc-en"); + gpio_direction_output(BABBAGE_26M_OSC_EN, 1); + + /* Drive USB_CLK_EN_B line low */ + gpio_request(BABBAGE_USB_CLK_EN_B, "usb-clk_en_b"); + gpio_direction_output(BABBAGE_USB_CLK_EN_B, 0); + + /* De-assert USB PHY RESETB */ + gpio_request(BABBAGE_PHY_RESET, "usb-phy-reset"); + gpio_direction_output(BABBAGE_PHY_RESET, 1); + + /* hphone_det_b */ + gpio_request(BABBAGE_HEADPHONE_DET, "hphone-det"); + gpio_direction_input(BABBAGE_HEADPHONE_DET); + + /* audio_clk_en_b */ + gpio_request(BABBAGE_AUDIO_CLK_EN, "audio-clk-en"); + gpio_direction_output(BABBAGE_AUDIO_CLK_EN, 0); + + /* power key */ + gpio_request(BABBAGE_POWER_KEY, "power-key"); + gpio_direction_input(BABBAGE_POWER_KEY); + + if (cpu_is_mx51_rev(CHIP_REV_3_0) > 0) { + /* DVI_I2C_ENB = 0 tristates the DVI I2C level shifter */ + gpio_request(BABBAGE_DVI_I2C_EN, "dvi-i2c-en"); + gpio_direction_output(BABBAGE_DVI_I2C_EN, 0); + } + + /* Deassert VGA reset to free i2c bus */ + gpio_request(BABBAGE_VGA_RESET, "vga-reset"); + gpio_direction_output(BABBAGE_VGA_RESET, 1); + + /* LCD related gpio */ + gpio_request(BABBAGE_DISP_BRIGHTNESS_CTL, "disp-brightness-ctl"); + gpio_request(BABBAGE_LVDS_POWER_DOWN, "lvds-power-down"); + gpio_request(BABBAGE_LCD_3V3_ON, "lcd-3v3-on"); + gpio_request(BABBAGE_LCD_5V_ON, "lcd-5v-on"); + gpio_direction_output(BABBAGE_DISP_BRIGHTNESS_CTL, 0); + gpio_direction_output(BABBAGE_LVDS_POWER_DOWN, 0); + gpio_direction_output(BABBAGE_LCD_3V3_ON, 0); + gpio_direction_output(BABBAGE_LCD_5V_ON, 0); + + /* Camera reset */ + gpio_request(BABBAGE_CAM_RESET, "cam-reset"); + gpio_direction_output(BABBAGE_CAM_RESET, 1); + + /* Camera low power */ + gpio_request(BABBAGE_CAM_LOW_POWER, "cam-low-power"); + gpio_direction_output(BABBAGE_CAM_LOW_POWER, 0); + + /* OSC_EN */ + gpio_request(BABBAGE_OSC_EN_B, "osc-en"); + gpio_direction_output(BABBAGE_OSC_EN_B, 1); + + if (enable_w1) { + /* OneWire */ + struct pad_desc onewire = MX51_PAD_OWIRE_LINE__OWIRE_LINE; + mxc_iomux_v3_setup_pad(&onewire); + } +} + /*! * Board specific initialization. */ @@ -917,14 +1299,16 @@ 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_ipu_data.csi_clk[0] = clk_get(NULL, "csi_mclk1"); + mxc_ipu_data.csi_clk[1] = clk_get(NULL, "csi_mclk2"); mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); clk_put(mxc_spdif_data.spdif_core_clk); /* SD card detect irqs */ - mxcsdhc2_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_6); - mxcsdhc2_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_6); - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0); + mxcsdhc2_device.resource[2].start = IOMUX_TO_IRQ_V3(BABBAGE_SD2_CD_2_5); + mxcsdhc2_device.resource[2].end = IOMUX_TO_IRQ_V3(BABBAGE_SD2_CD_2_5); + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ_V3(BABBAGE_SD1_CD); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ_V3(BABBAGE_SD1_CD); mxc_cpu_common_init(); mxc_register_gpios(); @@ -952,14 +1336,17 @@ 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); mxc_register_device(&mxc_ssi2_device, NULL); mxc_register_device(&mxc_alsa_spdif_device, &mxc_spdif_data); - mxc_register_device(&mxc_fec_device, NULL); + mxc_register_device(&mxc_fec_device, &fec_data); + mxc_register_device(&mxc_v4l2_device, NULL); + mxc_register_device(&mxc_v4l2out_device, NULL); + mxc_register_device(&mxc_android_pmem_device, &android_pmem_pdata); + mxc_register_device(&mxc_android_pmem_gpu_device, &android_pmem_gpu_pdata); + mxc_register_device(&android_usb_device, &android_usb_pdata); mx51_babbage_init_mc13892(); @@ -990,8 +1377,8 @@ static void __init mxc_board_init(void) if (cpu_is_mx51_rev(CHIP_REV_1_1) == 2) { sgtl5000_data.sysclk = 26000000; } - gpio_request(IOMUX_TO_GPIO(MX51_PIN_EIM_A23), "eim_a23"); - gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A23), 0); + gpio_request(BABBAGE_AUDAMP_STBY, "audioamp-stdby"); + gpio_direction_output(BABBAGE_AUDAMP_STBY, 0); mxc_register_device(&mxc_sgtl5000_device, &sgtl5000_data); mx5_usb_dr_init(); diff --git a/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c index 4aa15f3c2515..1626c95d54d2 100644 --- a/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c +++ b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c @@ -23,8 +23,8 @@ #include <linux/regulator/machine.h> #include <linux/mfd/mc13892/core.h> #include <mach/irqs.h> -#include "iomux.h" -#include "mx51_pins.h" +#include <mach/hardware.h> +#include <mach/iomux-mx51.h> /* * Convenience conversion. @@ -406,8 +406,8 @@ 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 */ + .irq = IOMUX_TO_IRQ_V3(8), + .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..bbacfc981d73 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> @@ -53,13 +51,16 @@ #include "mx51_pins.h" #include "devices_ccwmx51.h" #include "usb.h" +#include "linux/android_pmem.h" +#include "linux/usb/android.h" 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 +87,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) @@ -101,6 +145,36 @@ void mx51_set_num_cpu_wp(int num) return; } +#if defined CONFIG_ANDROID_PMEM +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem_adsp", + .start = 0, + .size = SZ_32M, + .no_allocator = 0, + .cached = PMEM_NONCACHE_NORMAL, +}; + +static struct android_pmem_platform_data android_pmem_gpu_pdata = { + .name = "pmem_gpu", + .start = 0, + .size = SZ_32M, + .no_allocator = 0, + .cached = PMEM_CACHE_ENABLE, +}; +#endif + +#ifdef CONFIG_USB_ANDROID +static struct android_usb_platform_data android_usb_pdata = { + .vendor_id = 0x0bb4, + .product_id = 0x0c01, + .adb_product_id = 0x0c02, + .version = 0x0100, + .product_name = "Android Phone", + .manufacturer_name = "Freescale", + .nluns = 3, +}; +#endif + /*! * 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 @@ -115,19 +189,48 @@ void mx51_set_num_cpu_wp(int num) static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { - char *str; struct tag *t; +#ifdef CONFIG_ANDROID + int size; +#else + char *str; struct tag *mem_tag = 0; 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; +#endif mxc_set_cpu_type(MXC_CPU_MX51); get_cpu_wp = mx51_get_cpu_wp; set_num_cpu_wp = mx51_set_num_cpu_wp; +#ifdef CONFIG_ANDROID + // TODO: Dual head support for Android. + // See commit 358e938e78b3380357f8f0c6dd54fa9fe4cc84c5 + // This commit removes Digi's dual display customizations + + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_MEM) + continue; + size = t->u.mem.size; + + android_pmem_pdata.start = + PHYS_OFFSET + size - android_pmem_pdata.size; + android_pmem_gpu_pdata.start = + android_pmem_pdata.start - android_pmem_gpu_pdata.size; + gpu_device.resource[5].start = + android_pmem_gpu_pdata.start - SZ_16M; + gpu_device.resource[5].end = + gpu_device.resource[5].start + SZ_16M - 1; + size -= android_pmem_pdata.size; + size -= android_pmem_gpu_pdata.size; + size -= SZ_16M; + t->u.mem.size = size; + } + +#else for_each_tag(mem_tag, tags) { if (mem_tag->hdr.tag == ATAG_MEM) { total_mem = mem_tag->u.mem.size; @@ -166,6 +269,9 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, } 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,12 +284,23 @@ 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 } +#endif + + } #define PWGT1SPIEN (1<<15) @@ -203,97 +320,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 +344,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,23 +371,29 @@ 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); +#ifdef CONFIG_ANDROID_PMEM + mxc_register_device(&mxc_android_pmem_device, &android_pmem_pdata); + mxc_register_device(&mxc_android_pmem_gpu_device, &android_pmem_gpu_pdata); #endif +#ifdef CONFIG_USB_ANDROID + mxc_register_device(&android_usb_device, &android_usb_pdata); +#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); + mxc_register_device(&mxc_fec_device, &fec_data); #endif #if defined(CONFIG_MTD_NAND_MXC) \ || defined(CONFIG_MTD_NAND_MXC_MODULE) \ @@ -356,6 +403,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 +418,26 @@ 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 +#if defined(CONFIG_KEYBOARD_GPIO) + mxc_register_device(&ccwmx51js_keys_gpio, &ccwmx51js_gpio_key_info); +#endif pm_power_off = mxc_power_off; } @@ -394,9 +447,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 +462,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..702d7d8912d0 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,16 +52,52 @@ #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 <mach/iomux-mx53.h> + #include "crm_regs.h" #include "devices.h" #include "usb.h" +#include <linux/android_pmem.h> +#include <linux/usb/android.h> + +#define ARM2_SD1_CD (0*32 + 1) /* GPIO_1_1 */ + +#define MX53_HP_DETECT (1*32 + 5) /* GPIO_2_5 */ + +#define EVK_SD3_CD (2*32 + 11) /* GPIO_3_11 */ +#define EVK_SD3_WP (2*32 + 12) /* GPIO_3_12 */ +#define EVK_SD1_CD (2*32 + 13) /* GPIO_3_13 */ +#define EVK_SD1_WP (2*32 + 14) /* GPIO_3_14 */ +#define ARM2_OTG_VBUS (2*32 + 22) /* GPIO_3_22 */ +#define MX53_DVI_PD (2*32 + 24) /* GPIO_3_24 */ +#define EVK_TS_INT (2*32 + 26) /* GPIO_3_26 */ +#define MX53_DVI_I2C (2*32 + 28) /* GPIO_3_28 */ +#define MX53_DVI_DETECT (2*32 + 31) /* GPIO_3_31 */ + +#define MX53_CAM_RESET (3*32 + 0) /* GPIO_4_0 */ +#define MX53_ESAI_RESET (3*32 + 2) /* GPIO_4_2 */ +#define MX53_CAN2_EN2 (3*32 + 4) /* GPIO_4_4 */ +#define MX53_12V_EN (3*32 + 5) /* GPIO_4_5 */ +#define ARM2_LCD_CONTRAST (3*32 + 20) /* GPIO_4_20 */ + +#define MX53_DVI_RESET (4*32 + 0) /* GPIO_5_0 */ +#define EVK_USB_HUB_RESET (4*32 + 20) /* GPIO_5_20 */ +#define MX53_TVIN_PWR (4*32 + 23) /* GPIO_5_23 */ +#define MX53_CAN2_EN1 (4*32 + 24) /* GPIO_5_24 */ +#define MX53_TVIN_RESET (4*32 + 25) /* GPIO_5_25 */ + +#define EVK_OTG_VBUS (5*32 + 6) /* GPIO_6_6 */ + +#define EVK_FEC_PHY_RESET (6*32 + 6) /* GPIO_7_6 */ +#define EVK_USBH1_VBUS (6*32 + 8) /* GPIO_7_8 */ +#define MX53_PMIC_INT (6*32 + 11) /* GPIO_7_11 */ +#define MX53_CAN1_EN1 (6*32 + 12) /* GPIO_7_12 */ +#define MX53_CAN1_EN2 (6*32 + 13) /* GPIO_7_13 */ /*! * @file mach-mx53/mx53_evk.c @@ -69,11 +106,298 @@ * * @ingroup MSL_MX53 */ -extern void __init mx53_evk_io_init(void); +extern int __init mx53_evk_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; +static struct pad_desc mx53common_pads[] = { + MX53_PAD_EIM_WAIT__GPIO_5_0, + + MX53_PAD_EIM_OE__DI1_PIN7, + MX53_PAD_EIM_RW__DI1_PIN8, + + MX53_PAD_EIM_A25__DI0_D1_CS, + + MX53_PAD_EIM_D16__CSPI1_SCLK, + MX53_PAD_EIM_D17__CSPI1_MISO, + MX53_PAD_EIM_D18__CSPI1_MOSI, + + MX53_PAD_EIM_D20__SER_DISP0_CS, + + MX53_PAD_EIM_D23__DI0_D0_CS, + + MX53_PAD_EIM_D24__GPIO_3_24, + MX53_PAD_EIM_D26__GPIO_3_26, + + MX53_PAD_EIM_D29__DISPB0_SER_RS, + + MX53_PAD_EIM_D30__DI0_PIN11, + MX53_PAD_EIM_D31__DI0_PIN12, + + MX53_PAD_ATA_DA_1__GPIO_7_7, + MX53_PAD_ATA_DATA4__GPIO_2_4, + MX53_PAD_ATA_DATA5__GPIO_2_5, + MX53_PAD_ATA_DATA6__GPIO_2_6, + + MX53_PAD_SD2_CLK__SD2_CLK, + MX53_PAD_SD2_CMD__SD2_CMD, + MX53_PAD_SD2_DATA0__SD2_DAT0, + MX53_PAD_SD2_DATA1__SD2_DAT1, + MX53_PAD_SD2_DATA2__SD2_DAT2, + MX53_PAD_SD2_DATA3__SD2_DAT3, + MX53_PAD_ATA_DATA12__SD2_DAT4, + MX53_PAD_ATA_DATA13__SD2_DAT5, + MX53_PAD_ATA_DATA14__SD2_DAT6, + MX53_PAD_ATA_DATA15__SD2_DAT7, + + MX53_PAD_CSI0_D10__UART1_TXD, + MX53_PAD_CSI0_D11__UART1_RXD, + + MX53_PAD_ATA_BUFFER_EN__UART2_RXD, + MX53_PAD_ATA_DMARQ__UART2_TXD, + MX53_PAD_ATA_DIOR__UART2_RTS, + MX53_PAD_ATA_INTRQ__UART2_CTS, + + MX53_PAD_ATA_CS_0__UART3_TXD, + MX53_PAD_ATA_CS_1__UART3_RXD, + + MX53_PAD_KEY_COL0__AUD5_TXC, + MX53_PAD_KEY_ROW0__AUD5_TXD, + MX53_PAD_KEY_COL1__AUD5_TXFS, + MX53_PAD_KEY_ROW1__AUD5_RXD, + + MX53_PAD_CSI0_D7__GPIO_5_25, + + MX53_PAD_GPIO_2__MLBDAT, + MX53_PAD_GPIO_3__MLBCLK, + + MX53_PAD_GPIO_6__MLBSIG, + + MX53_PAD_GPIO_4__GPIO_1_4, + MX53_PAD_GPIO_7__GPIO_1_7, + MX53_PAD_GPIO_8__GPIO_1_8, + + MX53_PAD_GPIO_10__GPIO_4_0, + + MX53_PAD_KEY_COL2__TXCAN1, + MX53_PAD_KEY_ROW2__RXCAN1, + + /* CAN1 -- EN */ + MX53_PAD_GPIO_18__GPIO_7_13, + /* CAN1 -- STBY */ + MX53_PAD_GPIO_17__GPIO_7_12, + /* CAN1 -- NERR */ + MX53_PAD_GPIO_5__GPIO_1_5, + + MX53_PAD_KEY_COL4__TXCAN2, + MX53_PAD_KEY_ROW4__RXCAN2, + + /* CAN2 -- EN */ + MX53_PAD_CSI0_D6__GPIO_5_24, + /* CAN2 -- STBY */ + MX53_PAD_GPIO_14__GPIO_4_4, + /* CAN2 -- NERR */ + MX53_PAD_CSI0_D4__GPIO_5_22, + + MX53_PAD_GPIO_11__GPIO_4_1, + MX53_PAD_GPIO_12__GPIO_4_2, + MX53_PAD_GPIO_13__GPIO_4_3, + MX53_PAD_GPIO_16__GPIO_7_11, + MX53_PAD_GPIO_19__GPIO_4_5, + + /* DI0 display clock */ + MX53_PAD_DI0_DISP_CLK__DI0_DISP_CLK, + + /* DI0 data enable */ + MX53_PAD_DI0_PIN15__DI0_PIN15, + /* DI0 HSYNC */ + MX53_PAD_DI0_PIN2__DI0_PIN2, + /* DI0 VSYNC */ + MX53_PAD_DI0_PIN3__DI0_PIN3, + + MX53_PAD_DISP0_DAT0__DISP0_DAT0, + MX53_PAD_DISP0_DAT1__DISP0_DAT1, + MX53_PAD_DISP0_DAT2__DISP0_DAT2, + MX53_PAD_DISP0_DAT3__DISP0_DAT3, + MX53_PAD_DISP0_DAT4__DISP0_DAT4, + MX53_PAD_DISP0_DAT5__DISP0_DAT5, + MX53_PAD_DISP0_DAT6__DISP0_DAT6, + MX53_PAD_DISP0_DAT7__DISP0_DAT7, + MX53_PAD_DISP0_DAT8__DISP0_DAT8, + MX53_PAD_DISP0_DAT9__DISP0_DAT9, + MX53_PAD_DISP0_DAT10__DISP0_DAT10, + MX53_PAD_DISP0_DAT11__DISP0_DAT11, + MX53_PAD_DISP0_DAT12__DISP0_DAT12, + MX53_PAD_DISP0_DAT13__DISP0_DAT13, + MX53_PAD_DISP0_DAT14__DISP0_DAT14, + MX53_PAD_DISP0_DAT15__DISP0_DAT15, + MX53_PAD_DISP0_DAT16__DISP0_DAT16, + MX53_PAD_DISP0_DAT17__DISP0_DAT17, + MX53_PAD_DISP0_DAT18__DISP0_DAT18, + MX53_PAD_DISP0_DAT19__DISP0_DAT19, + MX53_PAD_DISP0_DAT20__DISP0_DAT20, + MX53_PAD_DISP0_DAT21__DISP0_DAT21, + MX53_PAD_DISP0_DAT22__DISP0_DAT22, + MX53_PAD_DISP0_DAT23__DISP0_DAT23, + + MX53_PAD_LVDS0_TX3_P__LVDS0_TX3, + MX53_PAD_LVDS0_CLK_P__LVDS0_CLK, + MX53_PAD_LVDS0_TX2_P__LVDS0_TX2, + MX53_PAD_LVDS0_TX1_P__LVDS0_TX1, + MX53_PAD_LVDS0_TX0_P__LVDS0_TX0, + + MX53_PAD_LVDS1_TX3_P__LVDS1_TX3, + MX53_PAD_LVDS1_CLK_P__LVDS1_CLK, + MX53_PAD_LVDS1_TX2_P__LVDS1_TX2, + MX53_PAD_LVDS1_TX1_P__LVDS1_TX1, + MX53_PAD_LVDS1_TX0_P__LVDS1_TX0, + + /* audio and CSI clock out */ + MX53_PAD_GPIO_0__SSI_EXT1_CLK, + + MX53_PAD_CSI0_D12__CSI0_D12, + MX53_PAD_CSI0_D13__CSI0_D13, + MX53_PAD_CSI0_D14__CSI0_D14, + MX53_PAD_CSI0_D15__CSI0_D15, + MX53_PAD_CSI0_D16__CSI0_D16, + MX53_PAD_CSI0_D17__CSI0_D17, + MX53_PAD_CSI0_D18__CSI0_D18, + MX53_PAD_CSI0_D19__CSI0_D19, + + MX53_PAD_CSI0_VSYNC__CSI0_VSYNC, + MX53_PAD_CSI0_MCLK__CSI0_HSYNC, + MX53_PAD_CSI0_PIXCLK__CSI0_PIXCLK, + /* Camera low power */ + MX53_PAD_CSI0_D5__GPIO_5_23, + + /* esdhc1 */ + MX53_PAD_SD1_CMD__SD1_CMD, + MX53_PAD_SD1_CLK__SD1_CLK, + MX53_PAD_SD1_DATA0__SD1_DATA0, + MX53_PAD_SD1_DATA1__SD1_DATA1, + MX53_PAD_SD1_DATA2__SD1_DATA2, + MX53_PAD_SD1_DATA3__SD1_DATA3, + + /* esdhc3 */ + MX53_PAD_ATA_DATA8__SD3_DAT0, + MX53_PAD_ATA_DATA9__SD3_DAT1, + MX53_PAD_ATA_DATA10__SD3_DAT2, + MX53_PAD_ATA_DATA11__SD3_DAT3, + MX53_PAD_ATA_DATA0__SD3_DAT4, + MX53_PAD_ATA_DATA1__SD3_DAT5, + MX53_PAD_ATA_DATA2__SD3_DAT6, + MX53_PAD_ATA_DATA3__SD3_DAT7, + MX53_PAD_ATA_RESET_B__SD3_CMD, + MX53_PAD_ATA_IORDY__SD3_CLK, + + /* FEC pins */ + MX53_PAD_FEC_MDIO__FEC_MDIO, + MX53_PAD_FEC_REF_CLK__FEC_REF_CLK, + MX53_PAD_FEC_RX_ER__FEC_RX_ER, + MX53_PAD_FEC_CRS_DV__FEC_CRS_DV, + MX53_PAD_FEC_RXD1__FEC_RXD1, + MX53_PAD_FEC_RXD0__FEC_RXD0, + MX53_PAD_FEC_TX_EN__FEC_TX_EN, + MX53_PAD_FEC_TXD1__FEC_TXD1, + MX53_PAD_FEC_TXD0__FEC_TXD0, + MX53_PAD_FEC_MDC__FEC_MDC, + + MX53_PAD_CSI0_D8__I2C1_SDA, + MX53_PAD_CSI0_D9__I2C1_SCL, + + MX53_PAD_KEY_COL3__I2C2_SCL, + MX53_PAD_KEY_ROW3__I2C2_SDA, +}; + +static struct pad_desc mx53evk_pads[] = { + /* USB OTG USB_OC */ + MX53_PAD_EIM_A24__GPIO_5_4, + + /* USB OTG USB_PWR */ + MX53_PAD_EIM_A23__GPIO_6_6, + + /* DISPB0_SER_CLK */ + MX53_PAD_EIM_D21__DISPB0_SER_CLK, + + /* DI0_PIN1 */ + MX53_PAD_EIM_D22__DISPB0_SER_DIN, + + /* DVI I2C ENABLE */ + MX53_PAD_EIM_D28__GPIO_3_28, + + /* DVI DET */ + MX53_PAD_EIM_D31__GPIO_3_31, + + /* SDHC1 SD_CD */ + MX53_PAD_EIM_DA13__GPIO_3_13, + + /* SDHC1 SD_WP */ + MX53_PAD_EIM_DA14__GPIO_3_14, + + /* SDHC3 SD_CD */ + MX53_PAD_EIM_DA11__GPIO_3_11, + + /* SDHC3 SD_WP */ + MX53_PAD_EIM_DA12__GPIO_3_12, + + /* PWM backlight */ + MX53_PAD_GPIO_1__PWMO, + + /* USB HOST USB_PWR */ + MX53_PAD_ATA_DA_2__GPIO_7_8, + + /* USB HOST USB_RST */ + MX53_PAD_CSI0_DATA_EN__GPIO_5_20, + + /* USB HOST CARD_ON */ + MX53_PAD_EIM_DA15__GPIO_3_15, + + /* USB HOST CARD_RST */ + MX53_PAD_ATA_DATA7__GPIO_2_7, + + /* USB HOST WAN_WAKE */ + MX53_PAD_EIM_D25__GPIO_3_25, + + /* FEC_RST */ + MX53_PAD_ATA_DA_0__GPIO_7_6, +}; + +static struct pad_desc mx53arm2_pads[] = { + /* USB OTG USB_OC */ + MX53_PAD_EIM_D21__GPIO_3_21, + + /* USB OTG USB_PWR */ + MX53_PAD_EIM_D22__GPIO_3_22, + + /* SDHC1 SD_CD */ + MX53_PAD_GPIO_1__GPIO_1_1, + + /* gpio backlight */ + MX53_PAD_DI0_PIN4__GPIO_4_20, +}; + +static struct pad_desc mx53_nand_pads[] = { + MX53_PAD_NANDF_CLE__NANDF_CLE, + MX53_PAD_NANDF_ALE__NANDF_ALE, + MX53_PAD_NANDF_WP_B__NANDF_WP_B, + MX53_PAD_NANDF_WE_B__NANDF_WE_B, + MX53_PAD_NANDF_RE_B__NANDF_RE_B, + MX53_PAD_NANDF_RB0__NANDF_RB0, + MX53_PAD_NANDF_CS0__NANDF_CS0, + MX53_PAD_NANDF_CS1__NANDF_CS1 , + MX53_PAD_NANDF_CS2__NANDF_CS2, + MX53_PAD_NANDF_CS3__NANDF_CS3 , + MX53_PAD_EIM_DA0__EIM_DA0, + MX53_PAD_EIM_DA1__EIM_DA1, + MX53_PAD_EIM_DA2__EIM_DA2, + MX53_PAD_EIM_DA3__EIM_DA3, + MX53_PAD_EIM_DA4__EIM_DA4, + MX53_PAD_EIM_DA5__EIM_DA5, + MX53_PAD_EIM_DA6__EIM_DA6, + MX53_PAD_EIM_DA7__EIM_DA7, +}; + /* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */ static struct cpu_wp cpu_wp_auto[] = { { @@ -84,7 +408,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 +417,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 +431,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 +458,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,}, }; @@ -147,9 +511,76 @@ static struct platform_pwm_backlight_data mxc_pwm_backlight_data = { .pwm_id = 1, .max_brightness = 255, .dft_brightness = 128, - .pwm_period_ns = 78770, + .pwm_period_ns = 50000, }; +static void flexcan_xcvr_enable(int id, int en) +{ + static int pwdn; + if (id < 0 || id > 1) + return; + + if (en) { + if (!(pwdn++)) + gpio_set_value(MX53_12V_EN, 1); + + if (id == 0) { + gpio_set_value(MX53_CAN1_EN1, 1); + gpio_set_value(MX53_CAN1_EN2, 1); + } else { + gpio_set_value(MX53_CAN2_EN1, 1); + gpio_set_value(MX53_CAN2_EN2, 1); + } + + } else { + if (!(--pwdn)) + gpio_set_value(MX53_12V_EN, 0); + + if (id == 0) { + gpio_set_value(MX53_CAN1_EN1, 0); + gpio_set_value(MX53_CAN1_EN2, 0); + } else { + gpio_set_value(MX53_CAN2_EN1, 0); + gpio_set_value(MX53_CAN2_EN2, 0); + } + } +} + +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,10 +592,74 @@ static struct mxc_vpu_platform_data mxc_vpu_data = { .reset = mx5_vpu_reset, }; -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, - int chipselect); +static struct fec_platform_data fec_data = { + .phy = PHY_INTERFACE_MODE_RMII, + .phy_mask = ~1UL, +}; + +/* workaround for ecspi chipselect pin may not keep correct level when idle */ +static void mx53_evk_gpio_spi_chipselect_active(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + { + struct pad_desc eim_d19_gpio = MX53_PAD_EIM_D19__GPIO_3_19; + struct pad_desc cspi_ss0 = MX53_PAD_EIM_EB2__CSPI_SS0; + + /* de-select SS1 of instance: ecspi1. */ + mxc_iomux_v3_setup_pad(&eim_d19_gpio); + mxc_iomux_v3_setup_pad(&cspi_ss0); + } + break; + case 0x2: + { + struct pad_desc eim_eb2_gpio = MX53_PAD_EIM_EB2__GPIO_2_30; + struct pad_desc cspi_ss1 = MX53_PAD_EIM_D19__CSPI_SS1; + + /* de-select SS0 of instance: ecspi1. */ + mxc_iomux_v3_setup_pad(&eim_eb2_gpio); + mxc_iomux_v3_setup_pad(&cspi_ss1); + } + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + +static void mx53_evk_gpio_spi_chipselect_inactive(int cspi_mode, int status, + int chipselect) +{ + switch (cspi_mode) { + case 1: + switch (chipselect) { + case 0x1: + break; + case 0x2: + break; + default: + break; + } + break; + case 2: + break; + case 3: + break; + default: + break; + } +} + static struct mxc_spi_master mxcspi1_data = { .maxchipselect = 4, .spi_version = 23, @@ -180,10 +675,143 @@ 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_offset = MXC_GPC_CNTR_OFFSET, + .gpc_vcr_offset = MXC_GPC_VCR_OFFSET, + .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET, + .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET, + .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET, + .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 pad_desc mx53esai_pads[] = { + MX53_PAD_FEC_MDIO__ESAI_SCKR, + MX53_PAD_FEC_REF_CLK__ESAI_FSR, + MX53_PAD_FEC_RX_ER__ESAI_HCKR, + MX53_PAD_FEC_CRS_DV__ESAI_SCKT, + MX53_PAD_FEC_RXD1__ESAI_FST, + MX53_PAD_FEC_RXD0__ESAI_HCKT, + MX53_PAD_FEC_TX_EN__ESAI_TX3_RX2, + MX53_PAD_FEC_TXD1__ESAI_TX2_RX3, + MX53_PAD_FEC_TXD0__ESAI_TX4_RX1, + MX53_PAD_FEC_MDC__ESAI_TX5_RX0, + MX53_PAD_NANDF_CS2__ESAI_TX0, + MX53_PAD_NANDF_CS3__ESAI_TX1, +}; + +void gpio_activate_esai_ports(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53esai_pads, + ARRAY_SIZE(mx53esai_pads)); +} + +static struct mxc_esai_platform_data esai_data = { + .activate_esai_ports = gpio_activate_esai_ports, +}; + +void gpio_cs42888_pdwn(int pdwn) +{ + if (pdwn) + gpio_set_value(MX53_ESAI_RESET, 0); + else + gpio_set_value(MX53_ESAI_RESET, 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(ARM2_OTG_VBUS, 0); + } else if (board_is_mx53_evk_a()) { + /* MX53 EVK board ver A*/ + /* Enable OTG VBus with GPIO low */ + gpio_set_value(EVK_OTG_VBUS, 0); + } else if (board_is_mx53_evk_b()) { + /* MX53 EVK board ver B*/ + /* Enable OTG VBus with GPIO high */ + gpio_set_value(EVK_OTG_VBUS, 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(ARM2_OTG_VBUS, 1); + } else if (board_is_mx53_evk_a()) { + /* MX53 EVK board ver A*/ + /* Disable OTG VBus with GPIO high */ + gpio_set_value(EVK_OTG_VBUS, 1); + } else if (board_is_mx53_evk_b()) { + /* MX53 EVK board ver B*/ + /* Disable OTG VBus with GPIO low */ + gpio_set_value(EVK_OTG_VBUS, 0); + } +} + +static void mx53_gpio_usbotg_driver_vbus(bool on) +{ + if (on) + gpio_usbotg_vbus_active(); + else + gpio_usbotg_vbus_inactive(); +} + +static void mx53_gpio_host1_driver_vbus(bool on) +{ + if (on) + gpio_set_value(EVK_USBH1_VBUS, 1); + else + gpio_set_value(EVK_USBH1_VBUS, 0); +} + +static void adv7180_pwdn(int pwdn) +{ + gpio_request(MX53_TVIN_PWR, "tvin-pwr"); + gpio_direction_output(MX53_TVIN_PWR, 0); + if (pwdn) + gpio_set_value(MX53_TVIN_PWR, 0); + else + gpio_set_value(MX53_TVIN_PWR, 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 +821,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 +869,19 @@ 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) -{ - enable_vga = 1; - return 1; -} -__setup("vga", vga_setup); - -static int __init tv_setup(char *s) +static void camera_pwdn(int pwdn) { - enable_tv = 1; - if (strcmp(s, "2") == 0 || strcmp(s, "=2") == 0) - enable_tv = 2; - return 1; + gpio_request(MX53_TVIN_PWR, "tvin-pwr"); + gpio_direction_output(MX53_TVIN_PWR, 0); + gpio_set_value(MX53_TVIN_PWR, pwdn); } -__setup("hdtv", tv_setup); static struct mxc_camera_platform_data camera_data = { .analog_regulator = "VSD", + .gpo_regulator = "VVIDEO", .mclk = 24000000, .csi = 0, + .pwdn = camera_pwdn, }; static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { @@ -334,6 +890,27 @@ 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, + }, +}; + +static void sii9022_hdmi_reset(void) +{ + gpio_set_value(MX53_DVI_RESET, 0); + msleep(10); + gpio_set_value(MX53_DVI_RESET, 1); + msleep(10); +} + +static struct mxc_lcd_platform_data sii9022_hdmi_data = { + .reset = sii9022_hdmi_reset, }; /* TO DO add platform data */ @@ -345,7 +922,7 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { { .type = "tsc2007", .addr = 0x48, - .irq = IOMUX_TO_IRQ(MX53_PIN_EIM_A25), + .irq = IOMUX_TO_IRQ_V3(EVK_TS_INT), }, { .type = "backlight-i2c", @@ -359,6 +936,40 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { .type = "eeprom", .addr = 0x50, }, + { + .type = "sii9022", + .addr = 0x39, + .platform_data = &sii9022_hdmi_data, + }, +}; + +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) @@ -367,9 +978,9 @@ static int sdhc_write_protect(struct device *dev) if (!board_is_mx53_arm2()) { if (to_platform_device(dev)->id == 0) - rc = gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_EIM_DA14)); + rc = gpio_get_value(EVK_SD1_WP); else - rc = gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_EIM_DA12)); + rc = gpio_get_value(EVK_SD3_WP); } return rc; @@ -380,14 +991,14 @@ static unsigned int sdhc_get_card_det_status(struct device *dev) int ret; if (board_is_mx53_arm2()) { if (to_platform_device(dev)->id == 0) - ret = gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_GPIO_1)); + ret = gpio_get_value(ARM2_SD1_CD); else ret = 1; } else { if (to_platform_device(dev)->id == 0) { - ret = gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_EIM_DA13)); + ret = gpio_get_value(EVK_SD1_CD); } else{ /* config the det pin for SDHC3 */ - ret = gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_EIM_DA11)); + ret = gpio_get_value(EVK_SD3_CD); } } @@ -410,13 +1021,170 @@ 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, .status = sdhc_get_card_det_status, .wp_status = sdhc_write_protect, .clock_mmc = "esdhc_clk", + .clk_always_on = 1, +}; + +/* 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) @@ -427,7 +1195,7 @@ return 0; static int headphone_det_status(void) { - return (gpio_get_value(IOMUX_TO_GPIO(MX53_PIN_ATA_DATA5)) == 0); + return (gpio_get_value(MX53_HP_DETECT) == 0); } static int mxc_sgtl5000_init(void); @@ -436,7 +1204,7 @@ static struct mxc_audio_platform_data sgtl5000_data = { .ssi_num = 1, .src_port = 2, .ext_port = 5, - .hp_irq = IOMUX_TO_IRQ(MX53_PIN_ATA_DATA5), + .hp_irq = IOMUX_TO_IRQ(MX53_HP_DETECT), .hp_status = headphone_det_status, .amp_enable = mxc_sgtl5000_amp_enable, .init = mxc_sgtl5000_init, @@ -474,6 +1242,139 @@ 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 = "BOOT", + .offset = 0, + .size = 7 * 1024 * 1024}, + { + .name = "MISC", + .offset = MTDPART_OFS_APPEND, + .size = 1 * 1024 * 1024}, + { + .name = "RECOVERY", + .offset = MTDPART_OFS_APPEND, + .size = 20 * 1024 * 1024}, + { + .name = "ROOT", + .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); + +static int __initdata enable_w1 = { 0 }; +static int __init w1_setup(char *__unused) +{ + enable_w1 = 1; + return cpu_is_mx53(); +} +__setup("w1", w1_setup); + + +static int __initdata enable_spdif = { 0 }; +static int __init spdif_setup(char *__unused) +{ + enable_spdif = 1; + return 1; +} +__setup("spdif", spdif_setup); + +static struct android_pmem_platform_data android_pmem_pdata = { + .name = "pmem_adsp", + .start = 0, + .size = SZ_64M, + .no_allocator = 0, + .cached = PMEM_NONCACHE_NORMAL, +}; + +static struct android_pmem_platform_data android_pmem_gpu_pdata = { + .name = "pmem_gpu", + .start = 0, + .size = SZ_32M, + .no_allocator = 0, + .cached = PMEM_CACHE_ENABLE, +}; + +static struct android_usb_platform_data android_usb_pdata = { + .vendor_id = 0x0bb4, + .product_id = 0x0c01, + .adb_product_id = 0x0c02, + .version = 0x0100, + .product_name = "Android Phone", + .manufacturer_name = "Freescale", + .nluns = 3, +}; + /*! * 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 @@ -495,17 +1396,38 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, int gpu_mem = SZ_128M; int fb_mem = SZ_32M; char *str; + int size; mxc_set_cpu_type(MXC_CPU_MX53); get_cpu_wp = mx53_evk_get_cpu_wp; set_num_cpu_wp = mx53_evk_set_num_cpu_wp; + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_MEM) + continue; + size = t->u.mem.size; + + android_pmem_pdata.start = + PHYS_OFFSET + size - android_pmem_pdata.size; + android_pmem_gpu_pdata.start = + android_pmem_pdata.start - android_pmem_gpu_pdata.size; + gpu_device.resource[5].start = + android_pmem_gpu_pdata.start - SZ_16M; + gpu_device.resource[5].end = + gpu_device.resource[5].start + SZ_16M - 1; + size -= android_pmem_pdata.size; + size -= android_pmem_gpu_pdata.size; + size -= SZ_16M; + t->u.mem.size = size; + } +#if 0 for_each_tag(mem_tag, tags) { if (mem_tag->hdr.tag == ATAG_MEM) { total_mem = mem_tag->u.mem.size; left_mem = total_mem - gpu_mem - fb_mem; break; + } } @@ -557,6 +1479,140 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, } #endif } +#endif +} + +static void __init mx53_evk_io_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx53common_pads, + ARRAY_SIZE(mx53common_pads)); + + if (board_is_mx53_arm2()) { + /* MX53 ARM2 CPU board */ + pr_info("MX53 ARM2 board \n"); + mxc_iomux_v3_setup_multiple_pads(mx53arm2_pads, + ARRAY_SIZE(mx53arm2_pads)); + + /* Config GPIO for OTG VBus */ + gpio_request(ARM2_OTG_VBUS, "otg-vbus"); + gpio_direction_output(ARM2_OTG_VBUS, 1); + + gpio_request(ARM2_SD1_CD, "sdhc1-cd"); + gpio_direction_input(ARM2_SD1_CD); /* SD1 CD */ + + gpio_request(ARM2_LCD_CONTRAST, "lcd-contrast"); + gpio_direction_output(ARM2_LCD_CONTRAST, 1); + } else { + /* MX53 EVK board */ + pr_info("MX53 EVK board \n"); + mxc_iomux_v3_setup_multiple_pads(mx53evk_pads, + ARRAY_SIZE(mx53evk_pads)); + + /* Host1 Vbus with GPIO high */ + gpio_request(EVK_USBH1_VBUS, "usbh1-vbus"); + gpio_direction_output(EVK_USBH1_VBUS, 1); + /* shutdown the Host1 Vbus when system bring up, + * Vbus will be opened in Host1 driver's probe function */ + gpio_set_value(EVK_USBH1_VBUS, 0); + + /* USB HUB RESET - De-assert USB HUB RESET_N */ + gpio_request(EVK_USB_HUB_RESET, "usb-hub-reset"); + gpio_direction_output(EVK_USB_HUB_RESET, 0); + msleep(1); + gpio_set_value(EVK_USB_HUB_RESET, 1); + + /* Config GPIO for OTG VBus */ + gpio_request(EVK_OTG_VBUS, "otg-vbus"); + gpio_direction_output(EVK_OTG_VBUS, 0); + if (board_is_mx53_evk_a()) /*rev A,"1" disable, "0" enable vbus*/ + gpio_set_value(EVK_OTG_VBUS, 1); + else if (board_is_mx53_evk_b()) /* rev B,"0" disable,"1" enable Vbus*/ + gpio_set_value(EVK_OTG_VBUS, 0); + + gpio_request(EVK_SD1_CD, "sdhc1-cd"); + gpio_direction_input(EVK_SD1_CD); /* SD1 CD */ + gpio_request(EVK_SD1_WP, "sdhc1-wp"); + gpio_direction_input(EVK_SD1_WP); /* SD1 WP */ + + /* SD3 CD */ + gpio_request(EVK_SD3_CD, "sdhc3-cd"); + gpio_direction_input(EVK_SD3_CD); + + /* SD3 WP */ + gpio_request(EVK_SD3_WP, "sdhc3-wp"); + gpio_direction_input(EVK_SD3_WP); + + /* reset FEC PHY */ + gpio_request(EVK_FEC_PHY_RESET, "fec-phy-reset"); + gpio_direction_output(EVK_FEC_PHY_RESET, 0); + msleep(1); + gpio_set_value(EVK_FEC_PHY_RESET, 1); + + gpio_request(MX53_ESAI_RESET, "fesai-reset"); + gpio_direction_output(MX53_ESAI_RESET, 0); + } + + /* DVI Detect */ + gpio_request(MX53_DVI_DETECT, "dvi-detect"); + gpio_direction_input(MX53_DVI_DETECT); + /* DVI Reset - Assert for i2c disabled mode */ + gpio_request(MX53_DVI_RESET, "dvi-reset"); + gpio_set_value(MX53_DVI_RESET, 0); + + /* DVI Power-down */ + gpio_request(MX53_DVI_PD, "dvi-pd"); + gpio_direction_output(MX53_DVI_PD, 1); + + /* DVI I2C enable */ + gpio_request(MX53_DVI_I2C, "dvi-i2c"); + gpio_direction_output(MX53_DVI_I2C, 0); + + mxc_iomux_v3_setup_multiple_pads(mx53_nand_pads, + ARRAY_SIZE(mx53_nand_pads)); + + gpio_request(MX53_PMIC_INT, "pmic-int"); + gpio_direction_input(MX53_PMIC_INT); /*PMIC_INT*/ + + /* headphone_det_b */ + gpio_request(MX53_HP_DETECT, "hp-detect"); + gpio_direction_input(MX53_HP_DETECT); + + /* power key */ + + /* LCD related gpio */ + + /* Camera reset */ + gpio_request(MX53_CAM_RESET, "cam-reset"); + gpio_direction_output(MX53_CAM_RESET, 1); + + /* TVIN reset */ + gpio_request(MX53_TVIN_RESET, "tvin-reset"); + gpio_direction_output(MX53_TVIN_RESET, 0); + msleep(5); + gpio_set_value(MX53_TVIN_RESET, 1); + + /* CAN1 enable GPIO*/ + gpio_request(MX53_CAN1_EN1, "can1-en1"); + gpio_direction_output(MX53_CAN1_EN1, 0); + + gpio_request(MX53_CAN1_EN2, "can1-en2"); + gpio_direction_output(MX53_CAN1_EN2, 0); + + /* CAN2 enable GPIO*/ + gpio_request(MX53_CAN2_EN1, "can2-en1"); + gpio_direction_output(MX53_CAN2_EN1, 0); + + gpio_request(MX53_CAN2_EN2, "can2-en2"); + gpio_direction_output(MX53_CAN2_EN2, 0); + + if (enable_spdif) { + struct pad_desc spdif_pin = MX53_PAD_GPIO_19__SPDIF_TX1; + mxc_iomux_v3_setup_pad(&spdif_pin); + } else { + /* GPIO for 12V */ + gpio_request(MX53_12V_EN, "12v-en"); + gpio_direction_output(MX53_12V_EN, 0); + } } /*! @@ -566,20 +1622,22 @@ 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()) { - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX53_PIN_GPIO_1); - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX53_PIN_GPIO_1); + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ_V3(ARM2_SD1_CD); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ_V3(ARM2_SD1_CD); mmc3_data.card_inserted_state = 1; mmc3_data.status = NULL; mmc3_data.wp_status = NULL; mmc1_data.wp_status = NULL; } else { - mxcsdhc3_device.resource[2].start = IOMUX_TO_IRQ(MX53_PIN_EIM_DA11); - mxcsdhc3_device.resource[2].end = IOMUX_TO_IRQ(MX53_PIN_EIM_DA11); - mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ(MX53_PIN_EIM_DA13); - mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ(MX53_PIN_EIM_DA13); + mxcsdhc3_device.resource[2].start = IOMUX_TO_IRQ_V3(EVK_SD3_CD); + mxcsdhc3_device.resource[2].end = IOMUX_TO_IRQ_V3(EVK_SD3_CD); + mxcsdhc1_device.resource[2].start = IOMUX_TO_IRQ_V3(EVK_SD1_CD); + mxcsdhc1_device.resource[2].end = IOMUX_TO_IRQ_V3(EVK_SD1_CD); } mxc_cpu_common_init(); @@ -596,7 +1654,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,41 +1663,60 @@ 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, ARRAY_SIZE(mxc_i2c1_board_info)); - + mxc_register_device(&mxc_android_pmem_device, &android_pmem_pdata); + mxc_register_device(&mxc_android_pmem_gpu_device, &android_pmem_gpu_pdata); + mxc_register_device(&android_usb_device, &android_usb_pdata); + mxc_register_device(&mxc_powerkey_device, NULL); mx53_evk_init_mc13892(); /* 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); + } + mxc_register_device(&mxc_v4l2_device, NULL); + mxc_register_device(&mxc_v4l2out_device, NULL); } static void __init mx53_evk_timer_init(void) diff --git a/arch/arm/mach-mx5/mx53_evk_pmic_mc13892.c b/arch/arm/mach-mx5/mx53_evk_pmic_mc13892.c index f8ec651cd459..be5f850fcf97 100644 --- a/arch/arm/mach-mx5/mx53_evk_pmic_mc13892.c +++ b/arch/arm/mach-mx5/mx53_evk_pmic_mc13892.c @@ -23,8 +23,8 @@ #include <linux/regulator/machine.h> #include <linux/mfd/mc13892/core.h> #include <mach/irqs.h> -#include "iomux.h" -#include "mx53_pins.h" + +#include <mach/iomux-mx53.h> /* * Convenience conversion. @@ -183,6 +183,8 @@ static struct regulator_init_data vvideo_init = { .min_uV = mV_to_uV(2500), .max_uV = mV_to_uV(2775), .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, } }; @@ -266,7 +268,7 @@ static struct regulator_init_data gpo4_init = { .name = "GPO4", } }; - +#if 0 /*! * the event handler for power on event */ @@ -274,20 +276,20 @@ static void power_on_evt_handler(void) { pr_info("pwr on event1 is received \n"); } - +#endif static int mc13892_regulator_init(struct mc13892 *mc13892) { unsigned int value; - pmic_event_callback_t power_key_event; +// pmic_event_callback_t power_key_event; int register_mask; pr_info("Initializing regulators for MX53 EVK \n"); - +#if 0 /* subscribe PWRON1 event to enable ON_OFF key */ power_key_event.param = NULL; power_key_event.func = (void *)power_on_evt_handler; pmic_event_subscribe(EVENT_PWRONI, power_key_event); - +#endif /* Bit 4 DRM: keep VSRTC and CLK32KMCU on for all states */ #if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE) value = BITFVAL(DRM, 1); @@ -337,7 +339,7 @@ static struct mc13892_platform_data mc13892_plat = { static struct i2c_board_info __initdata mc13892_i2c_device = { I2C_BOARD_INFO("mc13892", 0x08), - .irq = IOMUX_TO_IRQ(MX53_PIN_GPIO_16), + .irq = IOMUX_TO_IRQ_V3(203), .platform_data = &mc13892_plat, }; diff --git a/arch/arm/mach-mx5/pm.c b/arch/arm/mach-mx5/pm.c index a63d6e725e8f..b2bf2f8355fd 100644 --- a/arch/arm/mach-mx5/pm.c +++ b/arch/arm/mach-mx5/pm.c @@ -25,9 +25,15 @@ #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) +#define DATABAHN_CTL_REG0 0 +#define DATABAHN_CTL_REG19 0x4c +#define DATABAHN_CTL_REG79 0x13c +#define DATABAHN_PHY_REG25 0x264 + static struct cpu_wp *cpu_wp_tbl; static struct clk *cpu_clk; @@ -41,16 +47,17 @@ extern int set_cpu_freq(int wp); static struct device *pm_dev; struct clk *gpc_dvfs_clk; extern void cpu_do_suspend_workaround(u32 sdclk_iomux_addr); -extern void cpu_cortexa8_do_idle(void *); +extern void mx50_suspend(u32 databahn_addr); extern struct cpu_wp *(*get_cpu_wp)(int *wp); +extern void __iomem *databahn_base; extern int iram_ready; void *suspend_iram_base; void (*suspend_in_iram)(void *sdclk_iomux_addr) = NULL; +void __iomem *suspend_param1; -static int mx51_suspend_enter(suspend_state_t state) +static int mx5_suspend_enter(suspend_state_t state) { - void __iomem *sdclk_iomux_addr = IO_ADDRESS(IOMUXC_BASE_ADDR + 0x4b8); u32 * wake_src; /* Check that we have a wake up source. We don't want to suspend if not.*/ @@ -82,12 +89,15 @@ static int mx51_suspend_enter(suspend_state_t state) local_flush_tlb_all(); flush_cache_all(); - /* Run the suspend code from iRAM. */ - suspend_in_iram(sdclk_iomux_addr); + if (cpu_is_mx51() || cpu_is_mx53()) { + /* Run the suspend code from iRAM. */ + suspend_in_iram(suspend_param1); - /*clear the EMPGC0/1 bits */ - __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); + /*clear the EMPGC0/1 bits */ + __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); + __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); + } else + suspend_in_iram(databahn_base); } else { cpu_do_idle(); } @@ -99,7 +109,7 @@ static int mx51_suspend_enter(suspend_state_t state) /* * Called after processes are frozen, but before we shut down devices. */ -static int mx51_suspend_prepare(void) +static int mx5_suspend_prepare(void) { #if defined(CONFIG_CPU_FREQ) struct cpufreq_freqs freqs; @@ -122,7 +132,7 @@ static int mx51_suspend_prepare(void) /* * Called before devices are re-setup. */ -static void mx51_suspend_finish(void) +static void mx5_suspend_finish(void) { #if defined(CONFIG_CPU_FREQ) struct cpufreq_freqs freqs; @@ -145,35 +155,35 @@ static void mx51_suspend_finish(void) /* * Called after devices are re-setup, but before processes are thawed. */ -static void mx51_suspend_end(void) +static void mx5_suspend_end(void) { } -static int mx51_pm_valid(suspend_state_t state) +static int mx5_pm_valid(suspend_state_t state) { return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX); } -struct platform_suspend_ops mx51_suspend_ops = { - .valid = mx51_pm_valid, - .prepare = mx51_suspend_prepare, - .enter = mx51_suspend_enter, - .finish = mx51_suspend_finish, - .end = mx51_suspend_end, +struct platform_suspend_ops mx5_suspend_ops = { + .valid = mx5_pm_valid, + .prepare = mx5_suspend_prepare, + .enter = mx5_suspend_enter, + .finish = mx5_suspend_finish, + .end = mx5_suspend_end, }; -static int __devinit mx51_pm_probe(struct platform_device *pdev) +static int __devinit mx5_pm_probe(struct platform_device *pdev) { pm_dev = &pdev->dev; return 0; } -static struct platform_driver mx51_pm_driver = { +static struct platform_driver mx5_pm_driver = { .driver = { - .name = "mx51_pm", + .name = "mx5_pm", }, - .probe = mx51_pm_probe, + .probe = mx5_pm_probe, }; static int __init pm_init(void) @@ -181,19 +191,32 @@ static int __init pm_init(void) int cpu_wp_nr; unsigned long iram_paddr; - pr_info("Static Power Management for Freescale i.MX51\n"); - if (platform_driver_register(&mx51_pm_driver) != 0) { - printk(KERN_ERR "mx51_pm_driver register failed\n"); + pr_info("Static Power Management for Freescale i.MX5\n"); + if (platform_driver_register(&mx5_pm_driver) != 0) { + printk(KERN_ERR "mx5_pm_driver register failed\n"); return -ENODEV; } - suspend_set_ops(&mx51_suspend_ops); + suspend_set_ops(&mx5_suspend_ops); /* Move suspend routine into iRAM */ iram_alloc(SZ_4K, &iram_paddr); /* Need to remap the area here since we want the memory region to be executable. */ suspend_iram_base = __arm_ioremap(iram_paddr, SZ_4K, MT_HIGH_VECTORS); - memcpy(suspend_iram_base, cpu_do_suspend_workaround, SZ_4K); + + if (cpu_is_mx51() || cpu_is_mx53()) { + suspend_param1 = IO_ADDRESS(IOMUXC_BASE_ADDR + 0x4b8); + memcpy(suspend_iram_base, cpu_do_suspend_workaround, + SZ_4K); + } else if (cpu_is_mx50()) { + /* + * Need to run the suspend code from IRAM as the DDR needs + * to be put into self refresh mode manually. + */ + memcpy(suspend_iram_base, mx50_suspend, SZ_4K); + + suspend_param1 = databahn_base; + } suspend_in_iram = (void *)suspend_iram_base; cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); @@ -212,7 +235,7 @@ static int __init pm_init(void) static void __exit pm_cleanup(void) { /* Unregister the device structure */ - platform_driver_unregister(&mx51_pm_driver); + platform_driver_unregister(&mx5_pm_driver); } module_init(pm_init); 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..199c30e26947 100644 --- a/arch/arm/mach-mx5/system.c +++ b/arch/arm/mach-mx5/system.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <asm/io.h> #include <mach/hardware.h> +#include <mach/clock.h> #include <asm/proc-fns.h> #include <asm/system.h> #include "crm_regs.h" @@ -33,10 +34,13 @@ extern int mxc_jtag_enabled; extern int iram_ready; -static struct clk *gpc_dvfs_clk; - -extern void cpu_cortexa8_do_idle(void *addr); +extern void __iomem *ccm_base; +extern void __iomem *databahn_base; +extern void (*wait_in_iram)(void *ccm_addr, void *databahn_addr); +extern void *wait_in_iram_base; +extern void mx50_wait(u32 ccm_base, u32 databahn_addr); +static struct clk *gpc_dvfs_clk; /* set cpu low power mode before WFI instruction */ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) @@ -66,6 +70,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) if (mode == WAIT_UNCLOCKED_POWER_OFF) { ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET); ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY; + ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS; stop_mode = 0; } else { ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET); @@ -96,7 +101,8 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); if (cpu_is_mx51()) __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); - __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); + if (!cpu_is_mx50()) + __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); if (stop_mode) { __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); @@ -150,14 +156,21 @@ static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF; */ void arch_idle(void) { - if (likely(!mxc_jtag_enabled)) { +/* if (likely(!mxc_jtag_enabled)) */{ + struct clk *ddr_clk = clk_get(NULL, "ddr_clk"); if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); /* gpc clock is needed for SRPG */ clk_enable(gpc_dvfs_clk); mxc_cpu_lp_set(arch_idle_mode); - cpu_do_idle(); + if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) { + memcpy(wait_in_iram_base, mx50_wait, SZ_4K); + wait_in_iram = (void *)wait_in_iram_base; + wait_in_iram(ccm_base, databahn_base); + } else + cpu_do_idle(); clk_disable(gpc_dvfs_clk); + clk_put(ddr_clk); } } @@ -171,8 +184,99 @@ 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(); } + + +static int __mxs_reset_block(void __iomem *hwreg, int just_enable) +{ + u32 c; + int timeout; + + /* the process of software reset of IP block is done + in several steps: + + - clear SFTRST and wait for block is enabled; + - clear clock gating (CLKGATE bit); + - set the SFTRST again and wait for block is in reset; + - clear SFTRST and wait for reset completion. + */ + c = __raw_readl(hwreg); + c &= ~(1 << 31); /* clear SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1 << 31)) == 0) + break; + if (timeout <= 0) { + printk(KERN_ERR "%s(%p): timeout when enabling\n", + __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1 << 30); /* clear CLKGATE */ + __raw_writel(c, hwreg); + + if (!just_enable) { + c = __raw_readl(hwreg); + c |= (1 << 31); /* now again set SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* poll until CLKGATE set */ + if (__raw_readl(hwreg) & (1 << 30)) + break; + if (timeout <= 0) { + printk(KERN_ERR "%s(%p): timeout when resetting\n", + __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1 << 31); /* clear SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1 << 31)) == 0) + break; + if (timeout <= 0) { + printk(KERN_ERR "%s(%p): timeout when enabling " + "after reset\n", __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1 << 30); /* clear CLKGATE */ + __raw_writel(c, hwreg); + } + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1 << 30)) == 0) + break; + + if (timeout <= 0) { + printk(KERN_ERR "%s(%p): timeout when unclockgating\n", + __func__, hwreg); + return -ETIME; + } + + return 0; +} + +int mxs_reset_block(void __iomem *hwreg, int just_enable) +{ + int try = 10; + int r; + + while (try--) { + r = __mxs_reset_block(hwreg, just_enable); + if (!r) + break; + pr_debug("%s: try %d failed\n", __func__, 10 - try); + } + return r; +} 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..4f36379b8d64 100644 --- a/arch/arm/mach-mx5/usb_dr.c +++ b/arch/arm/mach-mx5/usb_dr.c @@ -18,12 +18,12 @@ #include <linux/fsl_devices.h> #include <mach/arc_otg.h> #include <mach/hardware.h> +#include <asm/delay.h> #include "usb.h" #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_EHCI_ARC_OTG) || defined(CONFIG_USB_GADGET_ARC) static int usbotg_init_ext(struct platform_device *pdev); static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata); -static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable); static void usbotg_clock_gate(bool on); /* @@ -40,7 +40,6 @@ static struct fsl_usb2_platform_data dr_utmi_config = { .gpio_usb_active = gpio_usbotg_hs_active, .gpio_usb_inactive = gpio_usbotg_hs_inactive, .usb_clock_for_pm = usbotg_clock_gate, - .wake_up_enable = _wake_up_enable, .transceiver = "utmi", }; @@ -48,6 +47,13 @@ static struct fsl_usb2_platform_data dr_utmi_config = { static int usbotg_init_ext(struct platform_device *pdev) { struct clk *usb_clk; + if (cpu_is_mx50()) { + usb_clk = clk_get(&pdev->dev, "usb_phy1_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + return usbotg_init(pdev); + } usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); @@ -69,6 +75,15 @@ static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata) { struct clk *usb_clk; + if (cpu_is_mx50()) { + usb_clk = clk_get(&pdata->pdev->dev, "usb_phy1_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + + usbotg_uninit(pdata); + return; + } + usb_clk = clk_get(NULL, "usboh3_clk"); clk_disable(usb_clk); clk_put(usb_clk); @@ -80,33 +95,149 @@ static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata) usbotg_uninit(pdata); } -static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable) +#define ENABLED_BY_HOST (0x1 << 0) +#define ENABLED_BY_DEVICE (0x1 << 1) +#if defined(CONFIG_USB_EHCI_ARC_OTG) && defined(CONFIG_USB_GADGET_ARC) +/* Below two macros are used at otg mode to indicate usb mode*/ +static u32 wakeup_irq_enable_src = 0; +static void __wakeup_irq_enable(bool on, int source) { - if (get_usb_mode(pdata) == FSL_USB_DR_DEVICE) { - if (enable) { + /* otg host and device share the OWIE bit, only when host and device + * all enable the wakeup irq, we can enable the OWIE bit + */ + if (on) { + wakeup_irq_enable_src |= source; + if (wakeup_irq_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) { USBCTRL |= UCTRL_OWIE; - USBCTRL_HOST2 |= UCTRL_H2OVBWK_EN; USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_CONF2; - } else { - USBCTRL &= ~UCTRL_OWIE; - USBCTRL_HOST2 &= ~UCTRL_H2OVBWK_EN; - USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CONF2; + printk("OTG wakeup irq is enabled\n"); } - } else { - if (enable) { - USBCTRL |= UCTRL_OWIE; - USBCTRL_HOST2 |= (1 << 5); - } else { - USBCTRL &= ~UCTRL_OWIE; - USBCTRL_HOST2 &= ~(1 << 5); + }else { + printk("OTG wakeup irq disable\n"); + USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CONF2; + USBCTRL &= ~UCTRL_OWIE; + wakeup_irq_enable_src &= ~source; + /* The interrupt must be disabled for at least 3 clock + * cycles of the standby clock(32k Hz) , that is 0.094 ms*/ + udelay(100); + } +} +#else +static void __wakeup_irq_enable(bool on, int source) +{ + if (on) { + USBCTRL |= UCTRL_OWIE; + USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_CONF2; + }else { + USBCTRL &= ~UCTRL_OWIE; + USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CONF2; + /* The interrupt must be disabled for at least 3 clock + * cycles of the standby clock(32k Hz) , that is 0.094 ms*/ + udelay(100); + } +} +#endif + +#ifdef CONFIG_USB_EHCI_ARC_OTG +static void _host_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable) +{ + __wakeup_irq_enable(enable, ENABLED_BY_HOST); + /* host only care the ID change wakeup event */ + if (enable) { + USBCTRL_HOST2 |= UCTRL_H2OIDWK_EN; + }else { + USBCTRL_HOST2 &= ~UCTRL_H2OIDWK_EN; + /* The interrupt must be disabled for at least 2 clock + * cycles of the standby clock(32k Hz) , that is 0.0625 ms*/ + udelay(100); + } +} +#endif + +#ifdef CONFIG_USB_GADGET_ARC +static void _device_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable) +{ + __wakeup_irq_enable(enable, ENABLED_BY_DEVICE); + /* if udc is not used by any gadget, we can not enable the vbus wakeup */ + if (!pdata->port_enables) + { + USBCTRL_HOST2 &= ~UCTRL_H2OVBWK_EN; + return; + } + if (enable) { + USBCTRL_HOST2 |= UCTRL_H2OVBWK_EN; + }else { + USBCTRL_HOST2 &= ~UCTRL_H2OVBWK_EN; + } +} +#endif + +#if defined(CONFIG_USB_EHCI_ARC_OTG) && defined(CONFIG_USB_GADGET_ARC) +static u32 low_power_enable_src = 0; +static void __phy_lowpower_suspend(bool enable, int source) +{ + if (enable) { + low_power_enable_src |= source; + if (low_power_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) { + UOG_PORTSC1 |= PORTSC_PHCD; + printk("OTG phy lowpower enable\n"); } + }else { + printk("OTG phy lowpower disable\n"); + UOG_PORTSC1 &= ~PORTSC_PHCD; + low_power_enable_src &= ~source; + } +} +#else +static void __phy_lowpower_suspend(bool enable, int source) +{ + if (enable) { + UOG_PORTSC1 |= PORTSC_PHCD; + }else { + UOG_PORTSC1 &= ~PORTSC_PHCD; } } +#endif + +#ifdef CONFIG_USB_EHCI_ARC_OTG +static void _host_phy_lowpower_suspend(bool enable) +{ + __phy_lowpower_suspend(enable, ENABLED_BY_HOST); +} +#endif + +#ifdef CONFIG_USB_GADGET_ARC +static void _device_phy_lowpower_suspend(bool enable) +{ + __phy_lowpower_suspend(enable, ENABLED_BY_DEVICE); +} +#endif static void usbotg_clock_gate(bool on) { struct clk *usb_clk; + if (cpu_is_mx50()) { + if (on) { + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + usb_clk = clk_get(NULL, "usb_phy1_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + } else { + usb_clk = clk_get(NULL, "usb_phy1_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + } + return; + } + if (on) { usb_clk = clk_get(NULL, "usb_ahb_clk"); clk_enable(usb_clk); @@ -140,6 +271,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 @@ -149,11 +287,15 @@ void __init mx5_usb_dr_init(void) #endif #ifdef CONFIG_USB_EHCI_ARC_OTG dr_utmi_config.operating_mode = DR_HOST_MODE; + dr_utmi_config.wake_up_enable = _host_wakeup_enable; + dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend; platform_device_add_data(&mxc_usbdr_host_device, &dr_utmi_config, sizeof(dr_utmi_config)); platform_device_register(&mxc_usbdr_host_device); #endif #ifdef CONFIG_USB_GADGET_ARC dr_utmi_config.operating_mode = DR_UDC_MODE; + dr_utmi_config.wake_up_enable = _device_wakeup_enable; + dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend; platform_device_add_data(&mxc_usbdr_udc_device, &dr_utmi_config, sizeof(dr_utmi_config)); platform_device_register(&mxc_usbdr_udc_device); #endif diff --git a/arch/arm/mach-mx5/usb_h1.c b/arch/arm/mach-mx5/usb_h1.c index 7f0c463d45c1..3c53ed8901ae 100644 --- a/arch/arm/mach-mx5/usb_h1.c +++ b/arch/arm/mach-mx5/usb_h1.c @@ -17,14 +17,15 @@ #include <linux/clk.h> #include <linux/platform_device.h> #include <linux/fsl_devices.h> +#include <asm/delay.h> #include <mach/arc_otg.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include "usb.h" #include "iomux.h" #include "mx51_pins.h" - - +//#undef pr_debug +//#define pr_debug printk /* * USB Host1 HS port */ @@ -70,25 +71,67 @@ static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable) { if (enable) USBCTRL |= UCTRL_H1WIE; - else + else { USBCTRL &= ~UCTRL_H1WIE; + /* The interrupt must be disabled for at least 3 + * cycles of the standby clock(32k Hz) , that is 0.094 ms*/ + udelay(100); + } +} + +static void _phy_lowpower_suspend(bool enable) +{ + if (enable) { + UH1_PORTSC1 |= PORTSC_PHCD; + }else { + UH1_PORTSC1 &= ~PORTSC_PHCD; + } } 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 (cpu_is_mx50()) { + if (on) { + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + } else { + usb_clk = clk_get(NULL, "usb_ahb_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + } + return; + } + if (cpu_is_mx53()) { + usb_clk = clk_get(NULL, "usb_phy2_clk"); + if (on) { + clk_enable(usb_clk); + } else { + clk_disable(usb_clk); + } + clk_put(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 +152,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(NULL, "usb_phy2_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); } ret = fsl_usb_host_init(pdev); @@ -143,7 +190,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(NULL, "usb_phy2_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); } + fsl_usb_host_uninit(pdata); } @@ -156,9 +208,14 @@ static struct fsl_usb2_platform_data usbh1_config = { .power_budget = 500, /* 500 mA max power */ .wake_up_enable = _wake_up_enable, .usb_clock_for_pm = usbotg_clock_gate, + .phy_lowpower_suspend = _phy_lowpower_suspend, .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()) { |