sbc8240.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Handle mapping of the flash memory access routines on the SBC8240 board.
  3. *
  4. * Carolyn Smith, Tektronix, Inc.
  5. *
  6. * This code is GPLed
  7. *
  8. * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
  9. *
  10. */
  11. /*
  12. * The SBC8240 has 2 flash banks.
  13. * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors.
  14. * It contains the U-Boot code (7 sectors) and the environment (1 sector).
  15. * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector,
  16. * 2 x 8 KiB sectors, 1 x 16 KiB sectors.
  17. * Both parts are JEDEC compatible.
  18. */
  19. #include <linux/config.h>
  20. #include <linux/module.h>
  21. #include <linux/types.h>
  22. #include <linux/kernel.h>
  23. #include <asm/io.h>
  24. #include <linux/mtd/mtd.h>
  25. #include <linux/mtd/map.h>
  26. #include <linux/mtd/cfi.h>
  27. #ifdef CONFIG_MTD_PARTITIONS
  28. #include <linux/mtd/partitions.h>
  29. #endif
  30. #define DEBUG
  31. #ifdef DEBUG
  32. # define debugk(fmt,args...) printk(fmt ,##args)
  33. #else
  34. # define debugk(fmt,args...)
  35. #endif
  36. #define WINDOW_ADDR0 0xFFF00000 /* 512 KiB */
  37. #define WINDOW_SIZE0 0x00080000
  38. #define BUSWIDTH0 1
  39. #define WINDOW_ADDR1 0xFF000000 /* 4 MiB */
  40. #define WINDOW_SIZE1 0x00400000
  41. #define BUSWIDTH1 8
  42. #define MSG_PREFIX "sbc8240:" /* prefix for our printk()'s */
  43. #define MTDID "sbc8240-%d" /* for mtdparts= partitioning */
  44. static struct map_info sbc8240_map[2] = {
  45. {
  46. .name = "sbc8240 Flash Bank #0",
  47. .size = WINDOW_SIZE0,
  48. .bankwidth = BUSWIDTH0,
  49. },
  50. {
  51. .name = "sbc8240 Flash Bank #1",
  52. .size = WINDOW_SIZE1,
  53. .bankwidth = BUSWIDTH1,
  54. }
  55. };
  56. #define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map)
  57. /*
  58. * The following defines the partition layout of SBC8240 boards.
  59. *
  60. * See include/linux/mtd/partitions.h for definition of the
  61. * mtd_partition structure.
  62. *
  63. * The *_max_flash_size is the maximum possible mapped flash size
  64. * which is not necessarily the actual flash size. It must correspond
  65. * to the value specified in the mapping definition defined by the
  66. * "struct map_desc *_io_desc" for the corresponding machine.
  67. */
  68. #ifdef CONFIG_MTD_PARTITIONS
  69. static struct mtd_partition sbc8240_uboot_partitions [] = {
  70. /* Bank 0 */
  71. {
  72. .name = "U-boot", /* U-Boot Firmware */
  73. .offset = 0,
  74. .size = 0x00070000, /* 7 x 64 KiB sectors */
  75. .mask_flags = MTD_WRITEABLE, /* force read-only */
  76. },
  77. {
  78. .name = "environment", /* U-Boot environment */
  79. .offset = 0x00070000,
  80. .size = 0x00010000, /* 1 x 64 KiB sector */
  81. },
  82. };
  83. static struct mtd_partition sbc8240_fs_partitions [] = {
  84. {
  85. .name = "jffs", /* JFFS filesystem */
  86. .offset = 0,
  87. .size = 0x003C0000, /* 4 * 15 * 64KiB */
  88. },
  89. {
  90. .name = "tmp32",
  91. .offset = 0x003C0000,
  92. .size = 0x00020000, /* 4 * 32KiB */
  93. },
  94. {
  95. .name = "tmp8a",
  96. .offset = 0x003E0000,
  97. .size = 0x00008000, /* 4 * 8KiB */
  98. },
  99. {
  100. .name = "tmp8b",
  101. .offset = 0x003E8000,
  102. .size = 0x00008000, /* 4 * 8KiB */
  103. },
  104. {
  105. .name = "tmp16",
  106. .offset = 0x003F0000,
  107. .size = 0x00010000, /* 4 * 16KiB */
  108. }
  109. };
  110. /* trivial struct to describe partition information */
  111. struct mtd_part_def
  112. {
  113. int nums;
  114. unsigned char *type;
  115. struct mtd_partition* mtd_part;
  116. };
  117. static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];
  118. static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];
  119. #endif /* CONFIG_MTD_PARTITIONS */
  120. int __init init_sbc8240_mtd (void)
  121. {
  122. static struct _cjs {
  123. u_long addr;
  124. u_long size;
  125. } pt[NUM_FLASH_BANKS] = {
  126. {
  127. .addr = WINDOW_ADDR0,
  128. .size = WINDOW_SIZE0
  129. },
  130. {
  131. .addr = WINDOW_ADDR1,
  132. .size = WINDOW_SIZE1
  133. },
  134. };
  135. int devicesfound = 0;
  136. int i;
  137. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  138. printk (KERN_NOTICE MSG_PREFIX
  139. "Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);
  140. sbc8240_map[i].map_priv_1 =
  141. (unsigned long) ioremap (pt[i].addr, pt[i].size);
  142. if (!sbc8240_map[i].map_priv_1) {
  143. printk (MSG_PREFIX "failed to ioremap\n");
  144. return -EIO;
  145. }
  146. simple_map_init(&sbc8240_mtd[i]);
  147. sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);
  148. if (sbc8240_mtd[i]) {
  149. sbc8240_mtd[i]->module = THIS_MODULE;
  150. devicesfound++;
  151. }
  152. }
  153. if (!devicesfound) {
  154. printk(KERN_NOTICE MSG_PREFIX
  155. "No suppported flash chips found!\n");
  156. return -ENXIO;
  157. }
  158. #ifdef CONFIG_MTD_PARTITIONS
  159. sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
  160. sbc8240_part_banks[0].type = "static image";
  161. sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions);
  162. sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
  163. sbc8240_part_banks[1].type = "static file system";
  164. sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions);
  165. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  166. if (!sbc8240_mtd[i]) continue;
  167. if (sbc8240_part_banks[i].nums == 0) {
  168. printk (KERN_NOTICE MSG_PREFIX
  169. "No partition info available, registering whole device\n");
  170. add_mtd_device(sbc8240_mtd[i]);
  171. } else {
  172. printk (KERN_NOTICE MSG_PREFIX
  173. "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
  174. add_mtd_partitions (sbc8240_mtd[i],
  175. sbc8240_part_banks[i].mtd_part,
  176. sbc8240_part_banks[i].nums);
  177. }
  178. }
  179. #else
  180. printk(KERN_NOTICE MSG_PREFIX
  181. "Registering %d flash banks at once\n", devicesfound);
  182. for (i = 0; i < devicesfound; i++) {
  183. add_mtd_device(sbc8240_mtd[i]);
  184. }
  185. #endif /* CONFIG_MTD_PARTITIONS */
  186. return devicesfound == 0 ? -ENXIO : 0;
  187. }
  188. static void __exit cleanup_sbc8240_mtd (void)
  189. {
  190. int i;
  191. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  192. if (sbc8240_mtd[i]) {
  193. del_mtd_device (sbc8240_mtd[i]);
  194. map_destroy (sbc8240_mtd[i]);
  195. }
  196. if (sbc8240_map[i].map_priv_1) {
  197. iounmap ((void *) sbc8240_map[i].map_priv_1);
  198. sbc8240_map[i].map_priv_1 = 0;
  199. }
  200. }
  201. }
  202. module_init (init_sbc8240_mtd);
  203. module_exit (cleanup_sbc8240_mtd);
  204. MODULE_LICENSE ("GPL");
  205. MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");
  206. MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");