amazon.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Handle mapping of the flash memory access routines
  3. * on Amazon based devices.
  4. *
  5. * Copyright(C) 2004 [email protected]
  6. *
  7. * This code is GPLed
  8. *
  9. */
  10. // 000005:fchang 2005/6/2 Modified by Bingtao to double check if the EBU is enabled/disabled
  11. // 506231:tc.chen 2005/06/23 increase firmware partition size form 192KB to 256KB
  12. // 050701:linmars 2005/07/01 fix flash size wrong alignment after increase firmware partition
  13. // 165001:henryhsu 2005/8/18 Remove the support for Intel flash because of 2.1 not enough rootfs partition size
  14. // 165001:henryhsu 2005/9/7 Rolback to support INtel flash
  15. // 509071:tc.chen 2005/09/07 Reduced flash writing time
  16. // 511046:linmars 2005/11/04 change bootloader size from 128 into 64
  17. // 511241:linmars 2005/11/24 merge TaiChen's IRM patch
  18. // copyright 2005 infineon
  19. // copyright 2007 john crispin <[email protected]>
  20. // copyright 2007 felix fietkau <[email protected]>
  21. #include <linux/module.h>
  22. #include <linux/types.h>
  23. #include <linux/kernel.h>
  24. #include <asm/io.h>
  25. #include <linux/init.h>
  26. #include <linux/mtd/mtd.h>
  27. #include <linux/mtd/map.h>
  28. #include <linux/mtd/partitions.h>
  29. #include <linux/mtd/cfi.h>
  30. #include <linux/mutex.h>
  31. #include <asm/amazon/amazon.h>
  32. #define AMAZON_PCI_ARB_CTL_ALT 0xb100205c
  33. #define AMAZON_MTD_REG32( addr ) (*(volatile u32 *)(addr))
  34. static struct map_info amazon_map = {
  35. .name = "AMAZON_FLASH",
  36. .bankwidth = 2,
  37. .size = 0x1000000,
  38. };
  39. static map_word amazon_read16(struct map_info * map, unsigned long ofs)
  40. {
  41. map_word temp;
  42. ofs ^= 2;
  43. temp.x[0] = *((__u16 *) (map->virt + ofs));
  44. return temp;
  45. }
  46. static void amazon_write16(struct map_info *map, map_word d, unsigned long adr)
  47. {
  48. adr ^= 2;
  49. *((__u16 *) (map->virt + adr)) = d.x[0];
  50. }
  51. void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  52. {
  53. u8 *p;
  54. u8 *to_8;
  55. ssize_t l = len;
  56. from = (unsigned long) (from + map->virt);
  57. p = (u8 *) from;
  58. to_8 = (u8 *) to;
  59. while(len--){
  60. *to_8++ = *p++;
  61. }
  62. }
  63. void amazon_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  64. {
  65. u8 *p = (u8*) from;
  66. u8 *to_8;
  67. to += (unsigned long) map->virt;
  68. to_8 = (u8*)to;
  69. while(len--){
  70. *p++ = *to_8++;
  71. }
  72. }
  73. #define UBOOT_SIZE 0x40000
  74. static struct mtd_partition amazon_partitions[3] = {
  75. {
  76. name:"U-Boot", /* U-Boot firmware */
  77. offset:0x00000000,
  78. size:UBOOT_SIZE , /* 128k */
  79. },
  80. {
  81. name:"kernel", /* firmware */
  82. offset:UBOOT_SIZE,
  83. size:0x00100000, /* 192K */
  84. },
  85. {
  86. name:"rootfs", /* default partition */
  87. offset:0x00200000,
  88. size:0x00200000,
  89. },
  90. };
  91. unsigned long flash_start = 0x13000000;
  92. unsigned long flash_size = 0x800000;
  93. unsigned long uImage_size = 0x10000d;
  94. int find_uImage_size(unsigned long start_offset)
  95. {
  96. unsigned long magic;
  97. unsigned long temp;
  98. amazon_copy_from(&amazon_map, &magic, start_offset, 4);
  99. if (!(ntohl(magic) == 0x27051956)) {
  100. printk(KERN_INFO "amazon_mtd: invalid magic (0x%08X) of kernel at 0x%08lx \n", ntohl(magic), start_offset);
  101. return 0;
  102. }
  103. amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4);
  104. printk(KERN_INFO "amazon_mtd: kernel size is %ld \n", temp + 0x40);
  105. return temp + 0x40;
  106. }
  107. int __init init_amazon_mtd(void)
  108. {
  109. int ret = 0;
  110. unsigned long uimage_size;
  111. struct mtd_info *mymtd = NULL;
  112. struct mtd_partition *parts = NULL;
  113. *AMAZON_EBU_BUSCON0 = 0x1d7ff;
  114. amazon_map.read = amazon_read16;
  115. amazon_map.write = amazon_write16;
  116. amazon_map.copy_from = amazon_copy_from;
  117. amazon_map.copy_to = amazon_copy_to;
  118. amazon_map.phys = flash_start;
  119. amazon_map.virt = ioremap_nocache(flash_start, flash_size);
  120. if (!amazon_map.virt) {
  121. printk(KERN_WARNING "Failed to ioremap!\n");
  122. return -EIO;
  123. }
  124. mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map);
  125. if (!mymtd) {
  126. iounmap(amazon_map.virt);
  127. printk("probing failed\n");
  128. return -ENXIO;
  129. }
  130. mymtd->owner = THIS_MODULE;
  131. parts = &amazon_partitions[0];
  132. /* Some Samsung devices are containing a 16 MB flash chip with a bigger U-Boot partition. */
  133. if(mymtd->size == 0x01000000 && mymtd->erasesize == 0x00020000) {
  134. printk(KERN_INFO "amazon_mtd: Found big flash chip!\n");
  135. amazon_partitions[0].size = 0x60000;
  136. amazon_partitions[1].offset = 0x60000;
  137. uimage_size = find_uImage_size(amazon_partitions[1].offset);
  138. amazon_partitions[1].size = uimage_size;
  139. amazon_partitions[2].offset = 0x60000 + uimage_size;
  140. amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - mymtd->erasesize;
  141. } else {
  142. printk(KERN_INFO "amazon_mtd: Found small flash chip!\n");
  143. uimage_size = find_uImage_size(amazon_partitions[1].offset);
  144. amazon_partitions[1].size = uimage_size;
  145. amazon_partitions[2].offset = UBOOT_SIZE + uimage_size;
  146. amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
  147. }
  148. add_mtd_partitions(mymtd, parts, 3);
  149. printk(KERN_INFO "amazon_mtd: added %s flash with %dMB\n",
  150. amazon_map.name, mymtd->size >> 20);
  151. return 0;
  152. }
  153. static void __exit cleanup_amazon_mtd(void)
  154. {
  155. /* FIXME! */
  156. }
  157. module_init(init_amazon_mtd);
  158. module_exit(cleanup_amazon_mtd);
  159. MODULE_LICENSE("GPL");
  160. MODULE_AUTHOR("john crispin [email protected]");
  161. MODULE_DESCRIPTION("MTD map driver for AMAZON boards");