/* * * Handle mapping of the flash on Any ADI Boards * * Author: Leo @ Analog Devices * Copyright: (C) 2005 Analog Devices * * 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. * */ #if !defined(CONFIG_MTD_NAND) #include #include #include #include #include #include #include #include #include extern int board_flash_start,board_flash_size; unsigned int WINDOW_ADDR, WINDOW_SIZE; #ifdef CONFIG_SQUASHFS /* Define Flash Partition table for Squash FS */ /* Bootloader and Kernel partition sizes in KBytes */ #define BOOT_SIZE_8MB_16MB 2*64 /* 2 blocks of 64KBytes each */ #define BOOT_SIZE_32MB 4*128 /* 4 blocks of 128KBytes each */ #define JFFS2_RW_PART_8MB 512 /* 512 Kbytes 0.5 MB */ #if defined(CONFIG_FUSIV_VX185) && !defined(CONFIG_FUSIV_VX185_REV_A1) #define JFFS2_RW_PART_32MB 14 * 1024 /* 14MB */ #define KERNEL_SIZE 1536 /* 1.5MB; modify based on myfs_start */ #else #define JFFS2_RW_PART_32MB 1024 /* 1024 Kbytes 1 MB */ #define KERNEL_SIZE 896 /* 896KB; modify based on myfs_start */ #endif #define CUSTOM_PART_SIZE 128*128 /* 16384 KB = 16MBytes */ /* 8MB Flash 32MB flash ========= ========== _______________________ 0xbe000000 | | | Custom | | Partition | | (16 MBytes) | | | | | _______________________ 0xbf800000 |_______________________|0xbf000000 |uboot partition(128KB) | |uboot partition(512KB) | |_______________________|0xbf820000 |_______________________|0xbf080000 | JFFS2 read/write | | JFFS2 read/write | | partition (512KB) | | partition (1MB) | |_______________________|0xbf8a0000 |_______________________|0xbf180000 | Kernel | | Kernel | | partition | | partition | | (896KB; change based | | (896KB; change based | | on myfs_start) | | on myfs_start) | |_______________________|0xbf980000 |_______________________|0xbf260000 | |(myfs_start) | |(myfs_start) | FileSystem | | FileSystem | | partition | | partition | | (till end of Flash) | | (till end of Flash) | | | | | | | | | |_______________________|0xbfffffff |_______________________|0xbfffffff */ /* Define default partition information for 8MB and 16MB Flash */ static struct mtd_partition partition_info_8MB16MB[]={ { .name = "U-BOOT Partition", .offset = 0, /* 0xbf800000 */ .size = BOOT_SIZE_8MB_16MB * 1024 }, /* 2*64 KBytes */ { .name = "Ikanos JFFS2 RW Partition", .offset = BOOT_SIZE_8MB_16MB * 1024, /* 0xbf82000 */ .size = JFFS2_RW_PART_8MB * 1024 }, /* 4*128 KBytes */ { .name = "Ikanos Kernel Partition", .offset = (BOOT_SIZE_8MB_16MB + JFFS2_RW_PART_8MB) * 1024, /* 0xbf820000 */ .size = KERNEL_SIZE * 1024 }, { .name = "Ikanos Filesystem Partition", .offset = (BOOT_SIZE_8MB_16MB + JFFS2_RW_PART_8MB + KERNEL_SIZE) * 1024 } }; #if defined(CONFIG_FUSIV_VX185) && defined(CONFIG_FUSIV_VX185_REV_A1) #define VX185_FS_SIZE 96*128 /* 12 MB */ static struct mtd_partition partition_info_32MB[]={ { .name = "Ikanos Flash Custom Partition", .offset = 0, .size = CUSTOM_PART_SIZE * 1024 }, /* 16 Mbytes */ { .name = "Ikanos Filesystem Partition", .offset = CUSTOM_PART_SIZE * 1024, .size = VX185_FS_SIZE * 1024 }, /* 12 Mbytes */ { .name = "U-BOOT Partition", .offset = (CUSTOM_PART_SIZE + VX185_FS_SIZE) * 1024, .size = BOOT_SIZE_32MB * 1024}, /* 512 Kbytes */ { .name = "Ikanos Kernel Partition", .offset = (CUSTOM_PART_SIZE + VX185_FS_SIZE + BOOT_SIZE_32MB) * 1024, .size = KERNEL_SIZE * 1024 }, /* 896 Kbytes */ { .name = "Ikanos JFFS2 R/W Partition", .offset = (CUSTOM_PART_SIZE + VX185_FS_SIZE + BOOT_SIZE_32MB + KERNEL_SIZE) * 1024, .size = 0 } /* ~2.75 MB till end of flash */ }; #elif defined(CONFIG_FUSIV_VX185) static struct mtd_partition partition_info_32MB[]={ { .name = "U-BOOT Partition", .offset = 0, /* 0xbe000000 */ .size = BOOT_SIZE_32MB * 1024 }, /* 4*128 KBytes */ { .name = "Ikanos Kernel Partition", .offset = BOOT_SIZE_32MB *1024, /* 0xbe080000 */ .size = KERNEL_SIZE * 1024 }, /* 1.5MB */ { .name = "Ikanos JFFS2 RW Partition", .offset = (BOOT_SIZE_32MB + KERNEL_SIZE) *1024, /* 0xbe200000 */ .size = JFFS2_RW_PART_32MB * 1024 }, /* 14MB */ { .name = "Ikanos Filesystem Partition", .offset = (BOOT_SIZE_32MB + KERNEL_SIZE + JFFS2_RW_PART_32MB) * 1024, /* bf000000 */ .size = 0 } /* till end of flash */ }; #else /* Define default partition information for 32MB Flash */ static struct mtd_partition partition_info_32MB[]={ { .name = "U-BOOT Partition", .offset = CUSTOM_PART_SIZE * 1024, /* 0xbf000000 */ .size = BOOT_SIZE_32MB * 1024 }, /* 4*128 KBytes */ { .name = "Ikanos JFFS2 RW Partition", .offset = (CUSTOM_PART_SIZE + BOOT_SIZE_32MB)*1024, /* 0xbf080000 */ .size = JFFS2_RW_PART_32MB * 1024 }, /* 4*128 KBytes */ { .name = "Ikanos Kernel Partition", .offset = (CUSTOM_PART_SIZE + BOOT_SIZE_32MB + JFFS2_RW_PART_32MB)*1024, /* 0xbf180000 */ .size = KERNEL_SIZE * 1024 }, { .name = "Ikanos Filesystem Partition", .offset = (CUSTOM_PART_SIZE + BOOT_SIZE_32MB + JFFS2_RW_PART_32MB + KERNEL_SIZE)*1024, /* 0xBF260000 */ .size = 0 }, /* till end of flash */ { .name = "Ikanos Flash Custom Partition", .offset = 0, .size = CUSTOM_PART_SIZE*1024 } /* 16 Mbytes */ }; #endif /* * Custom partition has been made as partition 5 because the boot script rcS * always tries to mount jff2 read & write filesystem on /dev/mtdblock2 * irrespective of Flash size (8MB Flash doesn't have custom partition) * Note: this is valid for SquashFS only */ #elif defined(CONFIG_JFFS2_FS) /* Define Flash Partition table for JFFS2 */ /* 8MB Flash 32MB flash ========= ========== _______________________ 0xbe000000 | | | Custom | | Partition | | (16 MBytes) | | | | | _______________________ 0xbf800000 |_______________________|0xbf000000 |uboot partition(128KB) | |uboot partition(512KB) | |_______________________|0xbf820000 |_______________________|0xbf080000 | Kernel | | Kernel | | partition | | partition | | (896KB; change based | | (896KB; change based | | on myfs_start) | | on myfs_start) | |_______________________|0xbf900000 |_______________________|0xbf160000 | |(myfs_start) | |(myfs_start) | FileSystem | | FileSystem | | partition | | partition | | (till end of Flash) | | (till end of Flash) | | | | | | | | | |_______________________|0xbfffffff |_______________________|0xbfffffff */ /* Bootloader and Kernel partition sizes in KBytes */ #define BOOT_SIZE_8MB_16MB 2*64 /* 2 blocks of 64KBytes each */ #define BOOT_SIZE_32MB 4*128 /* 4 blocks of 128KBytes each */ #define KERNEL_SIZE 10*128 /* 1280KB; modify based on myfs_start */ #define CUSTOM_PART_SIZE 128*128 /* 16384 KB = 16MBytes */ /* Define default partition information for 8MB and 16MB Flash */ static struct mtd_partition partition_info_8MB16MB[]={ { .name = "U-BOOT Partition", .offset = 0, .size = BOOT_SIZE_8MB_16MB * 1024 }, /* 512 KBytes */ { .name = "Ikanos Kernel Partition", .offset = BOOT_SIZE_8MB_16MB * 1024, .size = KERNEL_SIZE * 1024 }, { .name = "Ikanos FileSystem Partition", .offset = (BOOT_SIZE_8MB_16MB + KERNEL_SIZE) * 1024 } }; #if defined(CONFIG_FUSIV_VX185) && defined(CONFIG_FUSIV_VX185_REV_A1) #define VX185_FS_SIZE 224*128 /* 28.6 MB */ static struct mtd_partition partition_info_32MB[]={ { .name = "Ikanos Filesystem Partition", .offset = 0, .size = VX185_FS_SIZE * 1024 }, /* 28.6 Mbytes */ { .name = "U-BOOT Partition", .offset = VX185_FS_SIZE * 1024, .size = BOOT_SIZE_32MB * 1024}, /* 512 Kbytes */ { .name = "Ikanos Kernel Partition", .offset = (VX185_FS_SIZE + BOOT_SIZE_32MB) * 1024, .size = 0 } /* ~ 3.5 Mbytes until end of flash */ }; #elif defined(CONFIG_FUSIV_VX185) static struct mtd_partition partition_info_32MB[]={ { .name = "U-BOOT Partition", .offset = 0, .size = BOOT_SIZE_32MB * 1024 }, /* 512 KBytes */ { .name = "Ikanos Kernel Partition", .offset = BOOT_SIZE_32MB * 1024, .size = KERNEL_SIZE * 1024 }, /* 1280KBytes */ { .name = "Ikanos FileSystem Partition", .offset = (BOOT_SIZE_32MB + KERNEL_SIZE) * 1024, .size = 0} /* 30.2MB, till end of flash */ }; #else #define VX180_FS_SIZE 128*128 static struct mtd_partition partition_info_32MB[]={ { .name = "U-BOOT Partition", .offset = VX180_FS_SIZE * 1024, .size = BOOT_SIZE_32MB * 1024 }, /* 512 KBytes */ { .name = "Ikanos Kernel Partition", .offset = (VX180_FS_SIZE + BOOT_SIZE_32MB) * 1024, .size = 0}, /* 15.5 MB, till end of flash */ { .name = "Ikanos FileSystem Partition", .offset = 0, .size = VX180_FS_SIZE * 1024 } /* 16Mbytes */ }; #endif #endif /* * Custom partition which is first 16MB of Flash has been defined as * last partition (mtdblock4) as it is mostly unused. */ static unsigned int myfs_start = 0; static int __init setfs_start(char *str) { get_option(&str, &myfs_start); return 1; } static struct mtd_info *mymtd; struct map_info mb_map = { .name = "Ikanos flash", .phys = 0, .size = 0, .bankwidth = 2, }; int __init init_mb(void) { struct mtd_partition *partition_info = NULL; u8 num_partitions = 0; u32 tmp; WINDOW_ADDR = board_flash_start & 0x1FFFFFFF; WINDOW_SIZE = board_flash_size; tmp = myfs_start & 0x1FFFFFFF; //if(((tmp)<(WINDOW_ADDR+0x40000)) || (tmp>(WINDOW_ADDR+WINDOW_SIZE))) if((tmp(WINDOW_ADDR+WINDOW_SIZE))) panic("!!! File system start address(myfs_start) setting 0x%x is wrong. \n", myfs_start); mb_map.phys = WINDOW_ADDR; mb_map.size = WINDOW_SIZE; switch(board_flash_start) { case 0xbf800000: case 0xbf000000: printk("16MB Flash\n"); #ifdef CONFIG_SQUASHFS partition_info_8MB16MB[3].offset = (myfs_start &0x1FFFFFFF) - WINDOW_ADDR; partition_info_8MB16MB[2].size = partition_info_8MB16MB[3].offset - partition_info_8MB16MB[2].offset; num_partitions = 4; #elif defined(CONFIG_JFFS2_FS) partition_info_8MB16MB[2].offset = (myfs_start &0x1FFFFFFF) - WINDOW_ADDR; partition_info_8MB16MB[1].size = partition_info_8MB16MB[2].offset - partition_info_8MB16MB[1].offset; num_partitions = 3; #endif partition_info = partition_info_8MB16MB; break; case 0xbe000000: printk("32MB Flash\n"); #ifdef CONFIG_SQUASHFS /* Adjust filesystem location and kernel partition size if necessary * This is not possible for VX185 A1 */ #ifndef CONFIG_FUSIV_VX185_REV_A1 partition_info_32MB[3].offset = (myfs_start &0x1FFFFFFF) - WINDOW_ADDR; partition_info_32MB[2].size = partition_info_32MB[3].offset - partition_info_32MB[2].offset; #endif /* squashFS has one additional partition */ #if !defined(CONFIG_FUSIV_VX185_REV_A1) && defined(CONFIG_FUSIV_VX185) num_partitions = 4; #else num_partitions = 5; #endif #elif defined(CONFIG_JFFS2_FS) /* Adjust filesystem location and kernel partition size if necessary * This is not possible for VX185 A1 */ #ifndef CONFIG_FUSIV_VX185_REV_A1 partition_info_32MB[2].offset = (myfs_start &0x1FFFFFFF) - WINDOW_ADDR; partition_info_32MB[1].size = partition_info_32MB[2].offset - partition_info_32MB[1].offset; #endif num_partitions = 3; #endif partition_info = partition_info_32MB; break; } printk(KERN_NOTICE "On Board flash device: 0x%x at 0x%x\n", WINDOW_SIZE, WINDOW_ADDR); mb_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); if (!mb_map.virt) { printk("Failed to ioremap\n"); return -EIO; } simple_map_init(&mb_map); mymtd = do_map_probe("cfi_probe", &mb_map); if (mymtd) { mymtd->owner = THIS_MODULE; add_mtd_device(mymtd); printk("Adding MTD partitions\n"); add_mtd_partitions(mymtd, partition_info, num_partitions); return 0; } else printk("do_map_probe returned NULL\n"); iounmap((void *)mb_map.virt); return -ENXIO; } static void __exit cleanup_mb(void) { if (mymtd) { del_mtd_device(mymtd); map_destroy(mymtd); } if (mb_map.virt) { iounmap((void *)mb_map.virt); mb_map.virt = 0; } } module_init(init_mb); module_exit(cleanup_mb); __setup("myfs_start=", setfs_start); MODULE_AUTHOR("Leo @ Analog Devices"); MODULE_DESCRIPTION("MTD map driver Ikanos Fusiv vx180 board"); MODULE_LICENSE("GPL"); #endif