1/* 2 * linux/arch/arm/mach-nomadik/board-8815nhk.c 3 * 4 * Copyright (C) STMicroelectronics 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2, as 8 * published by the Free Software Foundation. 9 * 10 * NHK15 board specifc driver definition 11 */ 12#include <linux/types.h> 13#include <linux/kernel.h> 14#include <linux/init.h> 15#include <linux/platform_device.h> 16#include <linux/amba/bus.h> 17#include <linux/interrupt.h> 18#include <linux/gpio.h> 19#include <linux/mtd/mtd.h> 20#include <linux/mtd/nand.h> 21#include <linux/mtd/onenand.h> 22#include <linux/mtd/partitions.h> 23#include <linux/io.h> 24#include <asm/sizes.h> 25#include <asm/mach-types.h> 26#include <asm/mach/arch.h> 27#include <asm/mach/irq.h> 28#include <asm/mach/flash.h> 29 30#include <plat/mtu.h> 31 32#include <mach/setup.h> 33#include <mach/nand.h> 34#include <mach/fsmc.h> 35 36/* Initial value for SRC control register: all timers use MXTAL/8 source */ 37#define SRC_CR_INIT_MASK 0x00007fff 38#define SRC_CR_INIT_VAL 0x2aaa8000 39 40/* These addresses span 16MB, so use three individual pages */ 41static struct resource nhk8815_nand_resources[] = { 42 { 43 .name = "nand_addr", 44 .start = NAND_IO_ADDR, 45 .end = NAND_IO_ADDR + 0xfff, 46 .flags = IORESOURCE_MEM, 47 }, { 48 .name = "nand_cmd", 49 .start = NAND_IO_CMD, 50 .end = NAND_IO_CMD + 0xfff, 51 .flags = IORESOURCE_MEM, 52 }, { 53 .name = "nand_data", 54 .start = NAND_IO_DATA, 55 .end = NAND_IO_DATA + 0xfff, 56 .flags = IORESOURCE_MEM, 57 } 58}; 59 60static int nhk8815_nand_init(void) 61{ 62 /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */ 63 writel(0x0000000E, FSMC_PCR(0)); 64 writel(0x000D0A00, FSMC_PMEM(0)); 65 writel(0x00100A00, FSMC_PATT(0)); 66 67 /* enable access to the chip select area */ 68 writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0)); 69 70 return 0; 71} 72 73/* 74 * These partitions are the same as those used in the 2.6.20 release 75 * shipped by the vendor; the first two partitions are mandated 76 * by the boot ROM, and the bootloader area is somehow oversized... 77 */ 78static struct mtd_partition nhk8815_partitions[] = { 79 { 80 .name = "X-Loader(NAND)", 81 .offset = 0, 82 .size = SZ_256K, 83 }, { 84 .name = "MemInit(NAND)", 85 .offset = MTDPART_OFS_APPEND, 86 .size = SZ_256K, 87 }, { 88 .name = "BootLoader(NAND)", 89 .offset = MTDPART_OFS_APPEND, 90 .size = SZ_2M, 91 }, { 92 .name = "Kernel zImage(NAND)", 93 .offset = MTDPART_OFS_APPEND, 94 .size = 3 * SZ_1M, 95 }, { 96 .name = "Root Filesystem(NAND)", 97 .offset = MTDPART_OFS_APPEND, 98 .size = 22 * SZ_1M, 99 }, { 100 .name = "User Filesystem(NAND)", 101 .offset = MTDPART_OFS_APPEND, 102 .size = MTDPART_SIZ_FULL, 103 } 104}; 105 106static struct nomadik_nand_platform_data nhk8815_nand_data = { 107 .parts = nhk8815_partitions, 108 .nparts = ARRAY_SIZE(nhk8815_partitions), 109 .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING \ 110 | NAND_NO_READRDY | NAND_NO_AUTOINCR, 111 .init = nhk8815_nand_init, 112}; 113 114static struct platform_device nhk8815_nand_device = { 115 .name = "nomadik_nand", 116 .dev = { 117 .platform_data = &nhk8815_nand_data, 118 }, 119 .resource = nhk8815_nand_resources, 120 .num_resources = ARRAY_SIZE(nhk8815_nand_resources), 121}; 122 123/* These are the partitions for the OneNand device, different from above */ 124static struct mtd_partition nhk8815_onenand_partitions[] = { 125 { 126 .name = "X-Loader(OneNAND)", 127 .offset = 0, 128 .size = SZ_256K, 129 }, { 130 .name = "MemInit(OneNAND)", 131 .offset = MTDPART_OFS_APPEND, 132 .size = SZ_256K, 133 }, { 134 .name = "BootLoader(OneNAND)", 135 .offset = MTDPART_OFS_APPEND, 136 .size = SZ_2M-SZ_256K, 137 }, { 138 .name = "SysImage(OneNAND)", 139 .offset = MTDPART_OFS_APPEND, 140 .size = 4 * SZ_1M, 141 }, { 142 .name = "Root Filesystem(OneNAND)", 143 .offset = MTDPART_OFS_APPEND, 144 .size = 22 * SZ_1M, 145 }, { 146 .name = "User Filesystem(OneNAND)", 147 .offset = MTDPART_OFS_APPEND, 148 .size = MTDPART_SIZ_FULL, 149 } 150}; 151 152static struct onenand_platform_data nhk8815_onenand_data = { 153 .parts = nhk8815_onenand_partitions, 154 .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions), 155}; 156 157static struct resource nhk8815_onenand_resource[] = { 158 { 159 .start = 0x30000000, 160 .end = 0x30000000 + SZ_128K - 1, 161 .flags = IORESOURCE_MEM, 162 }, 163}; 164 165static struct platform_device nhk8815_onenand_device = { 166 .name = "onenand-flash", 167 .id = -1, 168 .dev = { 169 .platform_data = &nhk8815_onenand_data, 170 }, 171 .resource = nhk8815_onenand_resource, 172 .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), 173}; 174 175static void __init nhk8815_onenand_init(void) 176{ 177#ifdef CONFIG_MTD_ONENAND 178 /* Set up SMCS0 for OneNand */ 179 writel(0x000030db, FSMC_BCR(0)); 180 writel(0x02100551, FSMC_BTR(0)); 181#endif 182} 183 184#define __MEM_4K_RESOURCE(x) \ 185 .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} 186 187static struct amba_device uart0_device = { 188 .dev = { .init_name = "uart0" }, 189 __MEM_4K_RESOURCE(NOMADIK_UART0_BASE), 190 .irq = {IRQ_UART0, NO_IRQ}, 191}; 192 193static struct amba_device uart1_device = { 194 .dev = { .init_name = "uart1" }, 195 __MEM_4K_RESOURCE(NOMADIK_UART1_BASE), 196 .irq = {IRQ_UART1, NO_IRQ}, 197}; 198 199static struct amba_device *amba_devs[] __initdata = { 200 &uart0_device, 201 &uart1_device, 202}; 203 204static struct resource nhk8815_eth_resources[] = { 205 { 206 .name = "smc91x-regs", 207 .start = 0x34000000 + 0x300, 208 .end = 0x34000000 + SZ_64K - 1, 209 .flags = IORESOURCE_MEM, 210 }, { 211 .start = NOMADIK_GPIO_TO_IRQ(115), 212 .end = NOMADIK_GPIO_TO_IRQ(115), 213 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, 214 } 215}; 216 217static struct platform_device nhk8815_eth_device = { 218 .name = "smc91x", 219 .resource = nhk8815_eth_resources, 220 .num_resources = ARRAY_SIZE(nhk8815_eth_resources), 221}; 222 223static int __init nhk8815_eth_init(void) 224{ 225 int gpio_nr = 115; /* hardwired in the board */ 226 int err; 227 228 err = gpio_request(gpio_nr, "eth_irq"); 229 if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO); 230 if (!err) err = gpio_direction_input(gpio_nr); 231 if (err) 232 pr_err("Error %i in %s\n", err, __func__); 233 return err; 234} 235device_initcall(nhk8815_eth_init); 236 237static struct platform_device *nhk8815_platform_devices[] __initdata = { 238 &nhk8815_nand_device, 239 &nhk8815_onenand_device, 240 &nhk8815_eth_device, 241 /* will add more devices */ 242}; 243 244static void __init nomadik_timer_init(void) 245{ 246 u32 src_cr; 247 248 /* Configure timer sources in "system reset controller" ctrl reg */ 249 src_cr = readl(io_p2v(NOMADIK_SRC_BASE)); 250 src_cr &= SRC_CR_INIT_MASK; 251 src_cr |= SRC_CR_INIT_VAL; 252 writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); 253 254 /* Save global pointer to mtu, used by platform timer code */ 255 mtu_base = io_p2v(NOMADIK_MTU0_BASE); 256 257 nmdk_timer_init(); 258} 259 260static struct sys_timer nomadik_timer = { 261 .init = nomadik_timer_init, 262}; 263 264static void __init nhk8815_platform_init(void) 265{ 266 int i; 267 268 cpu8815_platform_init(); 269 nhk8815_onenand_init(); 270 platform_add_devices(nhk8815_platform_devices, 271 ARRAY_SIZE(nhk8815_platform_devices)); 272 273 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) 274 amba_device_register(amba_devs[i], &iomem_resource); 275} 276 277MACHINE_START(NOMADIK, "NHK8815") 278 /* Maintainer: ST MicroElectronics */ 279 .phys_io = NOMADIK_UART0_BASE, 280 .io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc, 281 .boot_params = 0x100, 282 .map_io = cpu8815_map_io, 283 .init_irq = cpu8815_init_irq, 284 .timer = &nomadik_timer, 285 .init_machine = nhk8815_platform_init, 286MACHINE_END 287