1/* 2 * linux/arch/arm/mach-omap2/board-apollon.c 3 * 4 * Copyright (C) 2005,2006 Samsung Electronics 5 * Author: Kyungmin Park <kyungmin.park@samsung.com> 6 * 7 * Modified from mach-omap/omap2/board-h4.c 8 * 9 * Code for apollon OMAP2 board. Should work on many OMAP2 systems where 10 * the bootloader passes the board-specific data to the kernel. 11 * Do not put any board specific code to this file; create a new machine 12 * type if you need custom low-level initializations. 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 as 16 * published by the Free Software Foundation. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/init.h> 21#include <linux/platform_device.h> 22#include <linux/mtd/mtd.h> 23#include <linux/mtd/partitions.h> 24#include <linux/mtd/onenand.h> 25#include <linux/irq.h> 26#include <linux/interrupt.h> 27#include <linux/delay.h> 28 29#include <asm/hardware.h> 30#include <asm/mach-types.h> 31#include <asm/mach/arch.h> 32#include <asm/mach/flash.h> 33 34#include <asm/arch/gpio.h> 35#include <asm/arch/mux.h> 36#include <asm/arch/usb.h> 37#include <asm/arch/board.h> 38#include <asm/arch/common.h> 39#include "prcm-regs.h" 40 41/* LED & Switch macros */ 42#define LED0_GPIO13 13 43#define LED1_GPIO14 14 44#define LED2_GPIO15 15 45#define SW_ENTER_GPIO16 16 46#define SW_UP_GPIO17 17 47#define SW_DOWN_GPIO58 58 48 49static struct mtd_partition apollon_partitions[] = { 50 { 51 .name = "X-Loader + U-Boot", 52 .offset = 0, 53 .size = SZ_128K, 54 .mask_flags = MTD_WRITEABLE, 55 }, 56 { 57 .name = "params", 58 .offset = MTDPART_OFS_APPEND, 59 .size = SZ_128K, 60 }, 61 { 62 .name = "kernel", 63 .offset = MTDPART_OFS_APPEND, 64 .size = SZ_2M, 65 }, 66 { 67 .name = "rootfs", 68 .offset = MTDPART_OFS_APPEND, 69 .size = SZ_16M, 70 }, 71 { 72 .name = "filesystem00", 73 .offset = MTDPART_OFS_APPEND, 74 .size = SZ_32M, 75 }, 76 { 77 .name = "filesystem01", 78 .offset = MTDPART_OFS_APPEND, 79 .size = MTDPART_SIZ_FULL, 80 }, 81}; 82 83static struct flash_platform_data apollon_flash_data = { 84 .parts = apollon_partitions, 85 .nr_parts = ARRAY_SIZE(apollon_partitions), 86}; 87 88static struct resource apollon_flash_resource = { 89 .start = APOLLON_CS0_BASE, 90 .end = APOLLON_CS0_BASE + SZ_128K, 91 .flags = IORESOURCE_MEM, 92}; 93 94static struct platform_device apollon_onenand_device = { 95 .name = "onenand", 96 .id = -1, 97 .dev = { 98 .platform_data = &apollon_flash_data, 99 }, 100 .num_resources = ARRAY_SIZE(&apollon_flash_resource), 101 .resource = &apollon_flash_resource, 102}; 103 104static struct resource apollon_smc91x_resources[] = { 105 [0] = { 106 .start = APOLLON_ETHR_START, /* Physical */ 107 .end = APOLLON_ETHR_START + 0xf, 108 .flags = IORESOURCE_MEM, 109 }, 110 [1] = { 111 .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), 112 .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ), 113 .flags = IORESOURCE_IRQ, 114 }, 115}; 116 117static struct platform_device apollon_smc91x_device = { 118 .name = "smc91x", 119 .id = -1, 120 .num_resources = ARRAY_SIZE(apollon_smc91x_resources), 121 .resource = apollon_smc91x_resources, 122}; 123 124static struct platform_device apollon_lcd_device = { 125 .name = "apollon_lcd", 126 .id = -1, 127}; 128 129static struct platform_device *apollon_devices[] __initdata = { 130 &apollon_onenand_device, 131 &apollon_smc91x_device, 132 &apollon_lcd_device, 133}; 134 135static inline void __init apollon_init_smc91x(void) 136{ 137 /* Make sure CS1 timings are correct */ 138 GPMC_CONFIG1_1 = 0x00011203; 139 GPMC_CONFIG2_1 = 0x001f1f01; 140 GPMC_CONFIG3_1 = 0x00080803; 141 GPMC_CONFIG4_1 = 0x1c091c09; 142 GPMC_CONFIG5_1 = 0x041f1f1f; 143 GPMC_CONFIG6_1 = 0x000004c4; 144 GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24); 145 udelay(100); 146 147 omap_cfg_reg(W4__24XX_GPIO74); 148 if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) { 149 printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", 150 APOLLON_ETHR_GPIO_IRQ); 151 return; 152 } 153 omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1); 154} 155 156static void __init omap_apollon_init_irq(void) 157{ 158 omap2_init_common_hw(); 159 omap_init_irq(); 160 omap_gpio_init(); 161 apollon_init_smc91x(); 162} 163 164static struct omap_uart_config apollon_uart_config __initdata = { 165 .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), 166}; 167 168static struct omap_mmc_config apollon_mmc_config __initdata = { 169 .mmc [0] = { 170 .enabled = 1, 171 .wire4 = 1, 172 .wp_pin = -1, 173 .power_pin = -1, 174 .switch_pin = -1, 175 }, 176}; 177 178static struct omap_lcd_config apollon_lcd_config __initdata = { 179 .ctrl_name = "internal", 180}; 181 182static struct omap_board_config_kernel apollon_config[] = { 183 { OMAP_TAG_UART, &apollon_uart_config }, 184 { OMAP_TAG_MMC, &apollon_mmc_config }, 185 { OMAP_TAG_LCD, &apollon_lcd_config }, 186}; 187 188static void __init apollon_led_init(void) 189{ 190 /* LED0 - AA10 */ 191 omap_cfg_reg(AA10_242X_GPIO13); 192 omap_request_gpio(LED0_GPIO13); 193 omap_set_gpio_direction(LED0_GPIO13, 0); 194 omap_set_gpio_dataout(LED0_GPIO13, 0); 195 /* LED1 - AA6 */ 196 omap_cfg_reg(AA6_242X_GPIO14); 197 omap_request_gpio(LED1_GPIO14); 198 omap_set_gpio_direction(LED1_GPIO14, 0); 199 omap_set_gpio_dataout(LED1_GPIO14, 0); 200 /* LED2 - AA4 */ 201 omap_cfg_reg(AA4_242X_GPIO15); 202 omap_request_gpio(LED2_GPIO15); 203 omap_set_gpio_direction(LED2_GPIO15, 0); 204 omap_set_gpio_dataout(LED2_GPIO15, 0); 205} 206 207static irqreturn_t apollon_sw_interrupt(int irq, void *ignored) 208{ 209 static unsigned int led0, led1, led2; 210 211 if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16)) 212 omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1); 213 else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17)) 214 omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1); 215 else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58)) 216 omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1); 217 218 return IRQ_HANDLED; 219} 220 221static void __init apollon_sw_init(void) 222{ 223 /* Enter SW - Y11 */ 224 omap_cfg_reg(Y11_242X_GPIO16); 225 omap_request_gpio(SW_ENTER_GPIO16); 226 omap_set_gpio_direction(SW_ENTER_GPIO16, 1); 227 /* Up SW - AA12 */ 228 omap_cfg_reg(AA12_242X_GPIO17); 229 omap_request_gpio(SW_UP_GPIO17); 230 omap_set_gpio_direction(SW_UP_GPIO17, 1); 231 /* Down SW - AA8 */ 232 omap_cfg_reg(AA8_242X_GPIO58); 233 omap_request_gpio(SW_DOWN_GPIO58); 234 omap_set_gpio_direction(SW_DOWN_GPIO58, 1); 235 236 set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING); 237 if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, 238 IRQF_SHARED, "enter sw", 239 &apollon_sw_interrupt)) 240 return; 241 set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING); 242 if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, 243 IRQF_SHARED, "up sw", 244 &apollon_sw_interrupt)) 245 return; 246 set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING); 247 if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, 248 IRQF_SHARED, "down sw", 249 &apollon_sw_interrupt)) 250 return; 251} 252 253static void __init omap_apollon_init(void) 254{ 255 apollon_led_init(); 256 apollon_sw_init(); 257 258 /* REVISIT: where's the correct place */ 259 omap_cfg_reg(W19_24XX_SYS_NIRQ); 260 261 /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ 262 CONTROL_DEVCONF |= (1 << 24); 263 264 /* 265 * Make sure the serial ports are muxed on at this point. 266 * You have to mux them off in device drivers later on 267 * if not needed. 268 */ 269 platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); 270 omap_board_config = apollon_config; 271 omap_board_config_size = ARRAY_SIZE(apollon_config); 272 omap_serial_init(); 273} 274 275static void __init omap_apollon_map_io(void) 276{ 277 omap2_map_common_io(); 278} 279 280MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") 281 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ 282 .phys_io = 0x48000000, 283 .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, 284 .boot_params = 0x80000100, 285 .map_io = omap_apollon_map_io, 286 .init_irq = omap_apollon_init_irq, 287 .init_machine = omap_apollon_init, 288 .timer = &omap_timer, 289MACHINE_END 290