Path: blob/master/arch/arm/mach-omap2/board-apollon.c
10817 views
/*1* linux/arch/arm/mach-omap2/board-apollon.c2*3* Copyright (C) 2005,2006 Samsung Electronics4* Author: Kyungmin Park <[email protected]>5*6* Modified from mach-omap/omap2/board-h4.c7*8* Code for apollon OMAP2 board. Should work on many OMAP2 systems where9* the bootloader passes the board-specific data to the kernel.10* Do not put any board specific code to this file; create a new machine11* type if you need custom low-level initializations.12*13* This program is free software; you can redistribute it and/or modify14* it under the terms of the GNU General Public License version 2 as15* published by the Free Software Foundation.16*/1718#include <linux/kernel.h>19#include <linux/init.h>20#include <linux/platform_device.h>21#include <linux/mtd/mtd.h>22#include <linux/mtd/partitions.h>23#include <linux/mtd/onenand.h>24#include <linux/delay.h>25#include <linux/leds.h>26#include <linux/err.h>27#include <linux/clk.h>28#include <linux/smc91x.h>29#include <linux/gpio.h>3031#include <mach/hardware.h>32#include <asm/mach-types.h>33#include <asm/mach/arch.h>34#include <asm/mach/flash.h>3536#include <plat/led.h>37#include <plat/usb.h>38#include <plat/board.h>39#include <plat/common.h>40#include <plat/gpmc.h>4142#include "mux.h"43#include "control.h"4445/* LED & Switch macros */46#define LED0_GPIO13 1347#define LED1_GPIO14 1448#define LED2_GPIO15 1549#define SW_ENTER_GPIO16 1650#define SW_UP_GPIO17 1751#define SW_DOWN_GPIO58 585253#define APOLLON_FLASH_CS 054#define APOLLON_ETH_CS 155#define APOLLON_ETHR_GPIO_IRQ 745657static struct mtd_partition apollon_partitions[] = {58{59.name = "X-Loader + U-Boot",60.offset = 0,61.size = SZ_128K,62.mask_flags = MTD_WRITEABLE,63},64{65.name = "params",66.offset = MTDPART_OFS_APPEND,67.size = SZ_128K,68},69{70.name = "kernel",71.offset = MTDPART_OFS_APPEND,72.size = SZ_2M,73},74{75.name = "rootfs",76.offset = MTDPART_OFS_APPEND,77.size = SZ_16M,78},79{80.name = "filesystem00",81.offset = MTDPART_OFS_APPEND,82.size = SZ_32M,83},84{85.name = "filesystem01",86.offset = MTDPART_OFS_APPEND,87.size = MTDPART_SIZ_FULL,88},89};9091static struct onenand_platform_data apollon_flash_data = {92.parts = apollon_partitions,93.nr_parts = ARRAY_SIZE(apollon_partitions),94};9596static struct resource apollon_flash_resource[] = {97[0] = {98.flags = IORESOURCE_MEM,99},100};101102static struct platform_device apollon_onenand_device = {103.name = "onenand-flash",104.id = -1,105.dev = {106.platform_data = &apollon_flash_data,107},108.num_resources = ARRAY_SIZE(apollon_flash_resource),109.resource = apollon_flash_resource,110};111112static void __init apollon_flash_init(void)113{114unsigned long base;115116if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {117printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");118return;119}120apollon_flash_resource[0].start = base;121apollon_flash_resource[0].end = base + SZ_128K - 1;122}123124static struct smc91x_platdata appolon_smc91x_info = {125.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,126.leda = RPC_LED_100_10,127.ledb = RPC_LED_TX_RX,128};129130static struct resource apollon_smc91x_resources[] = {131[0] = {132.flags = IORESOURCE_MEM,133},134[1] = {135.start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),136.end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),137.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,138},139};140141static struct platform_device apollon_smc91x_device = {142.name = "smc91x",143.id = -1,144.dev = {145.platform_data = &appolon_smc91x_info,146},147.num_resources = ARRAY_SIZE(apollon_smc91x_resources),148.resource = apollon_smc91x_resources,149};150151static struct platform_device apollon_lcd_device = {152.name = "apollon_lcd",153.id = -1,154};155156static struct omap_led_config apollon_led_config[] = {157{158.cdev = {159.name = "apollon:led0",160},161.gpio = LED0_GPIO13,162},163{164.cdev = {165.name = "apollon:led1",166},167.gpio = LED1_GPIO14,168},169{170.cdev = {171.name = "apollon:led2",172},173.gpio = LED2_GPIO15,174},175};176177static struct omap_led_platform_data apollon_led_data = {178.nr_leds = ARRAY_SIZE(apollon_led_config),179.leds = apollon_led_config,180};181182static struct platform_device apollon_led_device = {183.name = "omap-led",184.id = -1,185.dev = {186.platform_data = &apollon_led_data,187},188};189190static struct platform_device *apollon_devices[] __initdata = {191&apollon_onenand_device,192&apollon_smc91x_device,193&apollon_lcd_device,194&apollon_led_device,195};196197static inline void __init apollon_init_smc91x(void)198{199unsigned long base;200201unsigned int rate;202struct clk *gpmc_fck;203int eth_cs;204int err;205206gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */207if (IS_ERR(gpmc_fck)) {208WARN_ON(1);209return;210}211212clk_enable(gpmc_fck);213rate = clk_get_rate(gpmc_fck);214215eth_cs = APOLLON_ETH_CS;216217/* Make sure CS1 timings are correct */218gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);219220if (rate >= 160000000) {221gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);222gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);223gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);224gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);225gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);226} else if (rate >= 130000000) {227gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);228gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);229gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);230gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);231gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);232} else {/* rate = 100000000 */233gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);234gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);235gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);236gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);237gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);238}239240if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {241printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");242goto out;243}244apollon_smc91x_resources[0].start = base + 0x300;245apollon_smc91x_resources[0].end = base + 0x30f;246udelay(100);247248omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);249err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");250if (err) {251printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",252APOLLON_ETHR_GPIO_IRQ);253gpmc_cs_free(APOLLON_ETH_CS);254}255out:256clk_disable(gpmc_fck);257clk_put(gpmc_fck);258}259260static struct omap_usb_config apollon_usb_config __initdata = {261.register_dev = 1,262.hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */263264.pins[0] = 6,265};266267static struct omap_lcd_config apollon_lcd_config __initdata = {268.ctrl_name = "internal",269};270271static struct omap_board_config_kernel apollon_config[] __initdata = {272{ OMAP_TAG_LCD, &apollon_lcd_config },273};274275static void __init omap_apollon_init_early(void)276{277omap2_init_common_infrastructure();278omap2_init_common_devices(NULL, NULL);279}280281static struct gpio apollon_gpio_leds[] __initdata = {282{ LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */283{ LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */284{ LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4 */285};286287static void __init apollon_led_init(void)288{289omap_mux_init_signal("vlynq_clk.gpio_13", 0);290omap_mux_init_signal("vlynq_rx1.gpio_14", 0);291omap_mux_init_signal("vlynq_rx0.gpio_15", 0);292293gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));294}295296static void __init apollon_usb_init(void)297{298/* USB device */299/* DEVICE_SUSPEND */300omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);301gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");302omap2_usbfs_init(&apollon_usb_config);303}304305#ifdef CONFIG_OMAP_MUX306static struct omap_board_mux board_mux[] __initdata = {307{ .reg_offset = OMAP_MUX_TERMINATOR },308};309#endif310311static void __init omap_apollon_init(void)312{313u32 v;314315omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);316omap_board_config = apollon_config;317omap_board_config_size = ARRAY_SIZE(apollon_config);318319apollon_init_smc91x();320apollon_led_init();321apollon_flash_init();322apollon_usb_init();323324/* REVISIT: where's the correct place */325omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);326327/* LCD PWR_EN */328omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);329330/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */331v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);332v |= (1 << 24);333omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);334335/*336* Make sure the serial ports are muxed on at this point.337* You have to mux them off in device drivers later on338* if not needed.339*/340platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));341omap_serial_init();342}343344static void __init omap_apollon_map_io(void)345{346omap2_set_globals_242x();347omap242x_map_common_io();348}349350MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")351/* Maintainer: Kyungmin Park <[email protected]> */352.boot_params = 0x80000100,353.reserve = omap_reserve,354.map_io = omap_apollon_map_io,355.init_early = omap_apollon_init_early,356.init_irq = omap_init_irq,357.init_machine = omap_apollon_init,358.timer = &omap_timer,359MACHINE_END360361362