diff options
Diffstat (limited to 'arch/arm/mach-mx35/mx35evb.c')
-rw-r--r-- | arch/arm/mach-mx35/mx35evb.c | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/arch/arm/mach-mx35/mx35evb.c b/arch/arm/mach-mx35/mx35evb.c new file mode 100644 index 000000000000..527ed464fdc6 --- /dev/null +++ b/arch/arm/mach-mx35/mx35evb.c @@ -0,0 +1,396 @@ +/* + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/nodemask.h> +#include <linux/clk.h> +#include <linux/spi/spi.h> +#include <linux/platform_device.h> +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach/flash.h> +#endif + +#include <mach/hardware.h> +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> +#include <asm/mach/keypad.h> +#include <mach/memory.h> +#include <mach/gpio.h> + +#include "board-mx35evb.h" +#include "crm_regs.h" +#include "iomux.h" + +/*! + * @file mach-mx35/mx35evb.c + * + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX35 + */ + +unsigned int mx35evb_board_io; + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +/* MTD NOR flash */ + +#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE) + +static struct mtd_partition mxc_nor_partitions[] = { + { + .name = "Bootloader", + .size = 512 * 1024, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { + .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 /* force read-only */ + }, + { + .name = "Redboot config", + .size = MTDPART_SIZ_FULL, + .offset = 0x01FFF000, + .mask_flags = MTD_WRITEABLE /* force read-only */ + }, +}; + +static struct flash_platform_data mxc_flash_data = { + .map_name = "cfi_probe", + .width = 2, + .parts = mxc_nor_partitions, + .nr_parts = ARRAY_SIZE(mxc_nor_partitions), +}; + +static struct resource mxc_flash_resource = { + .start = 0xa0000000, + .end = 0xa0000000 + 0x04000000 - 1, + .flags = IORESOURCE_MEM, + +}; + +static struct platform_device mxc_nor_mtd_device = { + .name = "mxc_nor_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_flash_data, + }, + .num_resources = 1, + .resource = &mxc_flash_resource, +}; + +static void mxc_init_nor_mtd(void) +{ + (void)platform_device_register(&mxc_nor_mtd_device); +} +#else +static void mxc_init_nor_mtd(void) +{ +} +#endif + +/* MTD NAND flash */ + +#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) + +static struct mtd_partition mxc_nand_partitions[] = { + { + .name = "IPL-SPL", + .offset = 0, + .size = 256 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 4 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 96 * 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_nand_data = { + .parts = mxc_nand_partitions, + .nr_parts = ARRAY_SIZE(mxc_nand_partitions), + .width = 1, +}; + +static struct platform_device mxc_nand_mtd_device = { + .name = "mxc_nand_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static void mxc_init_nand_mtd(void) +{ + if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) + mxc_nand_data.width = 2; + + platform_device_register(&mxc_nand_mtd_device); +} +#else +static inline void mxc_init_nand_mtd(void) +{ +} +#endif + +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +static struct resource smsc911x_resources[] = { + { + .start = ENET_BASE_ADDRESS, + .end = ENET_BASE_ADDRESS + 0x100, + .flags = IORESOURCE_MEM,}, + { + .start = EXPIO_INT_ENET, + .end = EXPIO_INT_ENET, + .flags = IORESOURCE_IRQ,} +}; + +static struct platform_device mxc_smsc911x_device = { + .name = "smsc911x", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, +}; + +static void mxc_init_enet(void) +{ + int i; + /*reset ext uart in cpld */ + __raw_writew(PBC_BCTRL1_ENET_RST_B, PBC_BCTRL1_SET); + /*delay some time for reset finish */ + for (i = 0; i < 10000; i++) ; + __raw_writew(PBC_BCTRL1_ENET_RST_B, PBC_BCTRL1_CLR); + + platform_device_register(&mxc_smsc911x_device); +} +#else +static inline void mxc_init_enet(void) +{ +} +#endif + +#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) +unsigned int expio_intr_fec; + +EXPORT_SYMBOL(expio_intr_fec); +#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 + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mxc_cpu_init(); + +#ifdef CONFIG_DISCONTIGMEM + do { + int nid; + mi->nr_banks = MXC_NUMNODES; + for (nid = 0; nid < mi->nr_banks; nid++) + SET_NODE(mi, nid); + } while (0); +#endif +} + +/*! + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + mxc_cpu_common_init(); + mxc_clocks_init(); + early_console_setup(saved_command_line); + mxc_register_gpios(); + mx35evb_gpio_init(); + mxc_init_enet(); + mxc_init_nor_mtd(); + mxc_init_nand_mtd(); + +} + +#define PLL_PCTL_REG(brmo, pd, mfd, mfi, mfn) \ + (((brmo) << 31) + (((pd) - 1) << 26) + (((mfd) - 1) << 16) + \ + ((mfi) << 10) + mfn) + +/* For 24MHz input clock */ +#define PLL_665MHZ PLL_PCTL_REG(1, 1, 48, 13, 41) +#define PLL_532MHZ PLL_PCTL_REG(1, 1, 12, 11, 1) +#define PLL_399MHZ PLL_PCTL_REG(0, 1, 16, 8, 5) + +/* working point(wp): 0,1 - 133MHz; 2,3 - 266MHz; 4,5 - 399MHz;*/ +/* auto input clock table */ +static struct cpu_wp cpu_wp_auto[] = { + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 133000000, + .pdr0_reg = (0x2 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 133000000, + .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 266000000, + .pdr0_reg = (0x1 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 266000000, + .pdr0_reg = (0x5 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 399000000, + .pdr0_reg = (0x0 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_399MHZ, + .pll_rate = 399000000, + .cpu_rate = 399000000, + .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),}, +}; + +/* consumer input clock table */ +static struct cpu_wp cpu_wp_con[] = { + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 133000000, + .pdr0_reg = (0x6 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 133000000, + .pdr0_reg = (0xE << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 266000000, + .pdr0_reg = (0x2 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 266000000, + .pdr0_reg = (0xA << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 399000000, + .pdr0_reg = (0x1 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 399000000, + .pdr0_reg = (0x9 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 532000000, + .pdr0_reg = (0x0 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_532MHZ, + .pll_rate = 532000000, + .cpu_rate = 532000000, + .pdr0_reg = (0x8 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, + { + .pll_reg = PLL_665MHZ, + .pll_rate = 665000000, + .cpu_rate = 665000000, + .pdr0_reg = (0x7 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),}, +}; + +struct cpu_wp *get_cpu_wp(int *wp) +{ + if (__raw_readl(MXC_CCM_PDR0) & MXC_CCM_PDR0_AUTO_CON) { + *wp = 9; + return cpu_wp_con; + } else { + *wp = 6; + return cpu_wp_auto; + } +} + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX35EVB data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX35EVB, "Freescale MX35 EVB") + /* Maintainer: Freescale Semiconductor, 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 = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END |