diff options
Diffstat (limited to 'arch/arm/mach-mx3/mach-mx35_3ds.c')
-rw-r--r-- | arch/arm/mach-mx3/mach-mx35_3ds.c | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/mach-mx35_3ds.c b/arch/arm/mach-mx3/mach-mx35_3ds.c new file mode 100644 index 000000000000..7bd140f86314 --- /dev/null +++ b/arch/arm/mach-mx3/mach-mx35_3ds.c @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. + * + * Author: Fabio Estevam <fabio.estevam@freescale.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/memory.h> +#include <linux/gpio.h> +#include <linux/fsl_devices.h> +#include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> +#include <linux/mfd/mc9s08dz60/pmic.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> +#include <linux/delay.h> + +#include <asm/mach/flash.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx35.h> +#include <mach/board-mx35_3ds.h> +#include <mach/3ds_debugboard.h> +#include <mach/mmc.h> +#include <mach/spi.h> +#include <mach/iomux-v3.h> + +#include "devices-imx35.h" +#include "devices.h" +#include "crm_regs.h" + +/* + * Board specific pad setting. + */ +#define MX35_ESDHC1_CMD__PAD_CFG \ +( \ + PAD_CTL_PUE | \ + PAD_CTL_PKE | \ + PAD_CTL_HYS | \ + PAD_CTL_DSE_MAX | \ + PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SRE_FAST \ +) + +#define MX35_ESDHC1_CLK__PAD_CFG \ +( \ + PAD_CTL_PUE | \ + PAD_CTL_PKE | \ + PAD_CTL_DSE_MAX | \ + PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SRE_FAST \ +) + +#define MX35_ESDHC1_DATA__PAD_CFG \ + MX35_ESDHC1_CMD__PAD_CFG + +static const struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static int spi_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(1), + MXC_SPI_CS(2), + MXC_SPI_CS(3), +}; + +static const struct spi_imx_master spi_pdata = { + .chipselect = spi_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), +}; + +static const struct imxi2c_platform_data i2c_data = { + .bitrate = 100000, +}; + +static unsigned int sdhc_get_card_det_status(struct device *dev) +{ + unsigned int ret; + + if (board_is_rev(BOARD_REV_2)) + pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 7, 1); + + if (to_platform_device(dev)->id == 0) { + if (0 != pmic_gpio_get_designation_bit_val(2, &ret)) + printk(KERN_ERR "Get cd status error."); + return ret; + } + + return 0; +} + +static int sdhc_write_protect(struct device *dev) +{ + unsigned int rc = 0; + + if (0 != pmic_gpio_get_designation_bit_val(3, &rc)) + printk(KERN_ERR "Get wp status error."); + + return rc; +} + +static struct mxc_mmc_platform_data mmc1_data = { + .ocr_mask = MMC_VDD_32_33, +#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE) + .caps = MMC_CAP_4_BIT_DATA, +#else + .caps = MMC_CAP_8_BIT_DATA, +#endif + .min_clk = 150000, + .max_clk = 52000000, + /* Do not disable the eSDHC clk on MX35 3DS board, + * since SYSTEM can't boot up after the reset key + * is pressed when the SD/MMC boot mode is used. + * The root cause is that the ROM code don't ensure + * the SD/MMC clk is running when boot system. + * */ + .clk_always_on = 1, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "sdhc_clk", +}; + +/* MTD NOR flash */ +static struct mtd_partition mxc_nor_partitions[] = { + { + .name = "Bootloader", + .size = 512 * 1024, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "nor.Kernel", + .size = 4 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0, + }, { + .name = "nor.userfs", + .size = 30 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = 0, + }, { + .name = "nor.rootfs", + .size = 28 * 1024 * 1024, + .offset = MTDPART_OFS_APPEND, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "FIS directory", + .size = 12 * 1024, + .offset = 0x01FE0000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Redboot config", + .size = MTDPART_SIZ_FULL, + .offset = 0x01FFF000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct flash_platform_data mxc_nor_flash_pdata = { + .map_name = "cfi_probe", + .width = 2, + .parts = mxc_nor_partitions, + .nr_parts = ARRAY_SIZE(mxc_nor_partitions), +}; + +/* MTD NAND flash */ +static struct mtd_partition mxc_nand_partitions[] = { + { + .name = "nand.bootloader", + .offset = 0, + .size = 3 * 1024 * 1024, + }, { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 5 * 1024 * 1024, + }, { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024 * 1024, + }, { + .name = "nand.configure", + .offset = MTDPART_OFS_APPEND, + .size = 8 * 1024 * 1024, + }, { + .name = "nand.userfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data mxc_nandv2_pdata = { + .parts = mxc_nand_partitions, + .nr_parts = ARRAY_SIZE(mxc_nand_partitions), + .width = 1, +}; + +static void __init mxc_register_nandv2_devices(void) +{ + if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) + mxc_nandv2_pdata.width = 2; + + mxc_register_device(&mxc_nandv2_device, &mxc_nandv2_pdata); +} + +static void si4702_reset(void) +{ + pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 4, 0); + msleep(100); + pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 4, 1); + msleep(100); +} + +static void si4702_clock_ctl(int flag) +{ + pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 7, flag); +} + +static struct mxc_fm_platform_data si4702_data = { + .reg_vio = "VSD", + .reg_vdd = NULL, + .reset = si4702_reset, + .clock_ctl = si4702_clock_ctl, + .sksnr = 0, + .skcnt = 0, + .band = 0, + .space = 100, + .seekth = 0xa, +}; + +static int tsc2007_get_pendown_state(void) +{ + return !gpio_get_value(MX35_GPIO1_4); +} + +struct tsc2007_platform_data tsc2007_data = { + .model = 2007, + .x_plate_ohms = 400, + .get_pendown_state = tsc2007_get_pendown_state, +}; + +static struct mxc_camera_platform_data camera_data = { + .core_regulator = "SW1", + .io_regulator = "VAUDIO", + .analog_regulator = NULL, + .gpo_regulator = "PWGT1", + .mclk = 27000000, +}; + +static void adv7180_pwdn(int pwdn) +{ + pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 1, ~pwdn); +} + +static void adv7180_reset(void) +{ + pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 6, 0); + msleep(5); + pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 6, 1); + msleep(5); +} + +static struct mxc_tvin_platform_data adv7180_data = { + .dvddio_reg = NULL, + .dvdd_reg = "SW3", + .avdd_reg = "PWGT2", + .pvdd_reg = NULL, + .pwdn = adv7180_pwdn, + .reset = adv7180_reset, +}; + +static struct i2c_board_info mxc_i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("max8660", 0x34), + }, { I2C_BOARD_INFO("tsc2007", 0x48), + .platform_data = &tsc2007_data, + .irq = IOMUX_TO_IRQ(MX35_GPIO1_4), + }, { + I2C_BOARD_INFO("ov2640", 0x30), + .platform_data = (void *)&camera_data, + }, { + I2C_BOARD_INFO("sgtl5000-i2c", 0x0a), + }, { + I2C_BOARD_INFO("ak4647-i2c", 0x12), + }, { +#if defined(CONFIG_I2C_SLAVE_CLIENT) + I2C_BOARD_INFO("i2c-slave-client", 0x55), +#endif + }, { + I2C_BOARD_INFO("si4702", 0x10), + .platform_data = (void *)&si4702_data, + }, { + I2C_BOARD_INFO("adv7180", 0x21), + .platform_data = (void *)&adv7180_data, + }, +}; + +static struct platform_device *devices[] __initdata = { + &mxc_fec_device, + &mxc_dma_device, +}; + +static struct pad_cfg mx35pdk_pads[] = { + /* UART1 */ + {MX35_PAD_CTS1__UART1_CTS, }, + {MX35_PAD_RTS1__UART1_RTS, }, + {MX35_PAD_TXD1__UART1_TXD_MUX, }, + {MX35_PAD_RXD1__UART1_RXD_MUX, }, + /* FEC */ + {MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, }, + {MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, }, + {MX35_PAD_FEC_RX_DV__FEC_RX_DV, }, + {MX35_PAD_FEC_COL__FEC_COL,}, + {MX35_PAD_FEC_RDATA0__FEC_RDATA_0, }, + {MX35_PAD_FEC_TDATA0__FEC_TDATA_0, }, + {MX35_PAD_FEC_TX_EN__FEC_TX_EN, }, + {MX35_PAD_FEC_MDC__FEC_MDC, }, + {MX35_PAD_FEC_MDIO__FEC_MDIO, }, + {MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, }, + {MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, }, + {MX35_PAD_FEC_CRS__FEC_CRS, }, + {MX35_PAD_FEC_RDATA1__FEC_RDATA_1, }, + {MX35_PAD_FEC_TDATA1__FEC_TDATA_1, }, + {MX35_PAD_FEC_RDATA2__FEC_RDATA_2, }, + {MX35_PAD_FEC_TDATA2__FEC_TDATA_2, }, + {MX35_PAD_FEC_RDATA3__FEC_RDATA_3, }, + {MX35_PAD_FEC_TDATA3__FEC_TDATA_3, }, + /* USBOTG */ + {MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,}, + {MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, }, + + /* SD/MMC-SDHC1 */ + {MX35_PAD_SD1_CMD__ESDHC1_CMD, MX35_ESDHC1_CMD__PAD_CFG}, + {MX35_PAD_SD1_CLK__ESDHC1_CLK, MX35_ESDHC1_CLK__PAD_CFG}, + {MX35_PAD_SD1_DATA0__ESDHC1_DAT0, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD1_DATA1__ESDHC1_DAT1, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD1_DATA2__ESDHC1_DAT2, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD1_DATA3__ESDHC1_DAT3, MX35_ESDHC1_DATA__PAD_CFG}, +#if !defined(CONFIG_SDIO_UNIFI_FS) && !defined(CONFIG_SDIO_UNIFI_FS_MODULE) + {MX35_PAD_SD2_CMD__ESDHC1_DAT4, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD2_CLK__ESDHC1_DAT5, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD2_DATA0__ESDHC1_DAT6, MX35_ESDHC1_DATA__PAD_CFG}, + {MX35_PAD_SD2_DATA1__ESDHC1_DAT7, MX35_ESDHC1_DATA__PAD_CFG}, +#endif + /* Capature */ + {MX35_PAD_CAPTURE__GPIO1_4,}, +}; + +/* OTG config */ +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, +}; + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads_ext(mx35pdk_pads, + ARRAY_SIZE(mx35pdk_pads)); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + imx35_add_imx_uart0(&uart_pdata); + imx35_add_imx_uart1(&uart_pdata); + imx35_add_imx_uart2(&uart_pdata); + + imx35_add_spi_imx0(&spi_pdata); + imx35_add_spi_imx1(&spi_pdata); + + mxc_register_device(&mxc_otg_udc_device, &usb_pdata); + + mxc_register_device(&mxc_nor_mtd_device, &mxc_nor_flash_pdata); + + mxc_register_nandv2_devices(); + + i2c_register_board_info(0, mxc_i2c_board_info, + ARRAY_SIZE(mxc_i2c_board_info)); + imx35_add_imx_i2c0(&i2c_data); + + mx35_3stack_init_mc13892(); + mx35_3stack_init_mc9s08dz60(); + + imx35_add_imx_mmc0(&mmc1_data); + + if (mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT)) + printk(KERN_WARNING "Init of the debugboard failed, all " + "devices on the board are unusable.\n"); +} + +static void __init mx35pdk_timer_init(void) +{ + mx35_clocks_init(); +} + +struct sys_timer mx35pdk_timer = { + .init = mx35pdk_timer_init, +}; + +MACHINE_START(MX35_3DS, "Freescale MX35PDK") + /* Maintainer: Freescale Semiconductor, Inc */ + .phys_io = MX35_AIPS1_BASE_ADDR, + .io_pg_offst = ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = MX3x_PHYS_OFFSET + 0x100, + .map_io = mx35_map_io, + .init_irq = mx35_init_irq, + .init_machine = mxc_board_init, + .timer = &mx35pdk_timer, +MACHINE_END |