/* * linux/arch/arm/mach-omap2/board-2430sdp-flash.c * * Copyright (C) 2007 MontaVista Software, Inc. * Author: Kevin Hilman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #define ONENAND_MAP 0x20000000 #define GPMC_OFF_CONFIG1_0 0x60 static struct mtd_partition onenand_partitions[] = { { .name = "(OneNAND)X-Loader", .offset = 0, .size = 4*(64*2048), /* 0-3 blks reserved. Mandated by ROM code */ .mask_flags = MTD_WRITEABLE /* force read-only */ }, { .name = "(OneNAND)U-Boot", .offset = MTDPART_OFS_APPEND, .size = 2*(64*2048), .mask_flags = MTD_WRITEABLE /* force read-only */ }, { .name = "(OneNAND)U-Boot Environment", .offset = MTDPART_OFS_APPEND, .size = 1*(64*2048), }, { .name = "(OneNAND)Kernel", .offset = MTDPART_OFS_APPEND, .size = 4*(64*2048), }, { .name = "(OneNAND)File System", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, }, }; static struct omap_onenand_platform_data sdp_onenand_data = { .parts = onenand_partitions, .nr_parts = ARRAY_SIZE(onenand_partitions), .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ }; static struct platform_device sdp_onenand_device = { .name = "omap2-onenand", .id = -1, .dev = { .platform_data = &sdp_onenand_data, }, }; void __init sdp2430_flash_init(void) { unsigned long gpmc_base_add, gpmc_cs_base_add; unsigned char cs=0; gpmc_base_add = OMAP243X_GPMC_VIRT; while (cs < GPMC_CS_NUM) { int ret = 0; /* Each GPMC set for a single CS is at offset 0x30 */ gpmc_cs_base_add = (gpmc_base_add + GPMC_OFF_CONFIG1_0 + (cs*0x30)); /* xloader/Uboot would have programmed the oneNAND * base address for us This is a ugly hack. The proper * way of doing this is to pass the setup of u-boot up * to kernel using kernel params - something on the * lines of machineID. Check if oneNAND is * configured */ ret = __raw_readl(gpmc_cs_base_add + GPMC_CS_CONFIG7); if ((ret & 0x3F) == (ONENAND_MAP >> 24)) { /* Found it!! */ break; } cs++; } if (cs >= GPMC_CS_NUM) { printk("OneNAND: Unable to find oneNAND configuration in GPMC " " - not registering.\n"); return; } sdp_onenand_data.cs = cs; if (platform_device_register(&sdp_onenand_device) < 0) { printk(KERN_ERR "Unable to register OneNAND device\n"); return; } }