1/* 2 * Flash memory access on AMD Alchemy evaluation boards 3 * 4 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com> 5 */ 6 7#include <linux/init.h> 8#include <linux/module.h> 9#include <linux/types.h> 10#include <linux/kernel.h> 11 12#include <linux/mtd/mtd.h> 13#include <linux/mtd/map.h> 14#include <linux/mtd/partitions.h> 15 16#include <asm/io.h> 17 18#ifdef CONFIG_MIPS_PB1000 19#define BOARD_MAP_NAME "Pb1000 Flash" 20#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */ 21#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 22#endif 23 24#ifdef CONFIG_MIPS_PB1500 25#define BOARD_MAP_NAME "Pb1500 Flash" 26#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ 27#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 28#endif 29 30#ifdef CONFIG_MIPS_PB1100 31#define BOARD_MAP_NAME "Pb1100 Flash" 32#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ 33#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 34#endif 35 36#ifdef CONFIG_MIPS_PB1550 37#define BOARD_MAP_NAME "Pb1550 Flash" 38#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */ 39#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 40#endif 41 42#ifdef CONFIG_MIPS_PB1200 43#define BOARD_MAP_NAME "Pb1200 Flash" 44#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */ 45#define BOARD_FLASH_WIDTH 2 /* 16-bits */ 46#endif 47 48#ifdef CONFIG_MIPS_DB1000 49#define BOARD_MAP_NAME "Db1000 Flash" 50#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ 51#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 52#endif 53 54#ifdef CONFIG_MIPS_DB1500 55#define BOARD_MAP_NAME "Db1500 Flash" 56#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ 57#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 58#endif 59 60#ifdef CONFIG_MIPS_DB1100 61#define BOARD_MAP_NAME "Db1100 Flash" 62#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ 63#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 64#endif 65 66#ifdef CONFIG_MIPS_DB1550 67#define BOARD_MAP_NAME "Db1550 Flash" 68#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */ 69#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 70#endif 71 72#ifdef CONFIG_MIPS_DB1200 73#define BOARD_MAP_NAME "Db1200 Flash" 74#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ 75#define BOARD_FLASH_WIDTH 2 /* 16-bits */ 76#endif 77 78#ifdef CONFIG_MIPS_HYDROGEN3 79#define BOARD_MAP_NAME "Hydrogen3 Flash" 80#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */ 81#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 82#define USE_LOCAL_ACCESSORS /* why? */ 83#endif 84 85#ifdef CONFIG_MIPS_BOSPORUS 86#define BOARD_MAP_NAME "Bosporus Flash" 87#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ 88#define BOARD_FLASH_WIDTH 2 /* 16-bits */ 89#endif 90 91#ifdef CONFIG_MIPS_MIRAGE 92#define BOARD_MAP_NAME "Mirage Flash" 93#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ 94#define BOARD_FLASH_WIDTH 4 /* 32-bits */ 95#define USE_LOCAL_ACCESSORS /* why? */ 96#endif 97 98static struct map_info alchemy_map = { 99 .name = BOARD_MAP_NAME, 100}; 101 102static struct mtd_partition alchemy_partitions[] = { 103 { 104 .name = "User FS", 105 .size = BOARD_FLASH_SIZE - 0x00400000, 106 .offset = 0x0000000 107 },{ 108 .name = "YAMON", 109 .size = 0x0100000, 110 .offset = MTDPART_OFS_APPEND, 111 .mask_flags = MTD_WRITEABLE 112 },{ 113 .name = "raw kernel", 114 .size = (0x300000 - 0x40000), /* last 256KB is yamon env */ 115 .offset = MTDPART_OFS_APPEND, 116 } 117}; 118 119static struct mtd_info *mymtd; 120 121int __init alchemy_mtd_init(void) 122{ 123 struct mtd_partition *parts; 124 int nb_parts = 0; 125 unsigned long window_addr; 126 unsigned long window_size; 127 128 /* Default flash buswidth */ 129 alchemy_map.bankwidth = BOARD_FLASH_WIDTH; 130 131 window_addr = 0x20000000 - BOARD_FLASH_SIZE; 132 window_size = BOARD_FLASH_SIZE; 133#ifdef CONFIG_MIPS_MIRAGE_WHY 134 /* Boot ROM flash bank only; no user bank */ 135 window_addr = 0x1C000000; 136 window_size = 0x04000000; 137 /* USERFS from 0x1C00 0000 to 0x1FC00000 */ 138 alchemy_partitions[0].size = 0x03C00000; 139#endif 140 141 /* 142 * Static partition definition selection 143 */ 144 parts = alchemy_partitions; 145 nb_parts = ARRAY_SIZE(alchemy_partitions); 146 alchemy_map.size = window_size; 147 148 /* 149 * Now let's probe for the actual flash. Do it here since 150 * specific machine settings might have been set above. 151 */ 152 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n", 153 alchemy_map.bankwidth*8); 154 alchemy_map.virt = ioremap(window_addr, window_size); 155 mymtd = do_map_probe("cfi_probe", &alchemy_map); 156 if (!mymtd) { 157 iounmap(alchemy_map.virt); 158 return -ENXIO; 159 } 160 mymtd->owner = THIS_MODULE; 161 162 add_mtd_partitions(mymtd, parts, nb_parts); 163 return 0; 164} 165 166static void __exit alchemy_mtd_cleanup(void) 167{ 168 if (mymtd) { 169 del_mtd_partitions(mymtd); 170 map_destroy(mymtd); 171 iounmap(alchemy_map.virt); 172 } 173} 174 175module_init(alchemy_mtd_init); 176module_exit(alchemy_mtd_cleanup); 177 178MODULE_AUTHOR("Embedded Alley Solutions, Inc"); 179MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver"); 180MODULE_LICENSE("GPL"); 181