2 * Handle mapping of the flash memory access routines
3 * on Amazon based devices.
5 * Copyright(C) 2004 peng.liu@infineon.com
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
19 // copyright 2005 infineon
21 // copyright 2007 john crispin <blogic@openwrt.org>
22 // copyright 2007 felix fietkau <nbd@openwrt.org>
24 #include <linux/module.h>
25 #include <linux/types.h>
26 #include <linux/kernel.h>
29 #include <linux/init.h>
30 #include <linux/mtd/mtd.h>
31 #include <linux/mtd/map.h>
32 #include <linux/mtd/partitions.h>
33 #include <linux/mtd/cfi.h>
34 #include <linux/mutex.h>
35 #include <asm/amazon/amazon.h>
37 #define AMAZON_PCI_ARB_CTL_ALT 0xb100205c
38 #define AMAZON_MTD_REG32( addr ) (*(volatile u32 *)(addr))
41 static struct map_info amazon_map
= {
42 .name
= "AMAZON_FLASH",
47 static map_word
amazon_read16(struct map_info
* map
, unsigned long ofs
)
51 temp
.x
[0] = *((__u16
*) (map
->virt
+ ofs
));
55 static void amazon_write16(struct map_info
*map
, map_word d
, unsigned long adr
)
58 *((__u16
*) (map
->virt
+ adr
)) = d
.x
[0];
61 void amazon_copy_from(struct map_info
*map
, void *to
, unsigned long from
, ssize_t len
)
66 from
= (unsigned long) (from
+ map
->virt
);
74 void amazon_copy_to(struct map_info
*map
, unsigned long to
, const void *from
, ssize_t len
)
78 to
+= (unsigned long) map
->virt
;
85 #define UBOOT_SIZE 0x40000
87 static struct mtd_partition amazon_partitions
[3] = {
89 name
:"U-Boot", /* U-Boot firmware */
91 size
:UBOOT_SIZE
, /* 128k */
94 name
:"kernel", /* firmware */
96 size
:0x00100000, /* 192K */
99 name
:"rootfs", /* default partition */
106 unsigned long flash_start
= 0x13000000;
107 unsigned long flash_size
= 0x800000;
108 unsigned long uImage_size
= 0x10000d;
110 int find_uImage_size(unsigned long start_offset
)
114 amazon_copy_from(&amazon_map
, &magic
, start_offset
, 4);
115 if (!(ntohl(magic
) == 0x27051956)) {
116 printk(KERN_INFO
"amazon_mtd: invalid magic (0x%08X) of kernel at 0x%08lx \n", ntohl(magic
), start_offset
);
119 amazon_copy_from(&amazon_map
, &temp
, start_offset
+ 12, 4);
120 printk(KERN_INFO
"amazon_mtd: kernel size is %ld \n", temp
+ 0x40);
124 int __init
init_amazon_mtd(void)
127 unsigned long uimage_size
;
128 struct mtd_info
*mymtd
= NULL
;
129 struct mtd_partition
*parts
= NULL
;
131 *AMAZON_EBU_BUSCON0
= 0x1d7ff;
133 amazon_map
.read
= amazon_read16
;
134 amazon_map
.write
= amazon_write16
;
135 amazon_map
.copy_from
= amazon_copy_from
;
136 amazon_map
.copy_to
= amazon_copy_to
;
138 amazon_map
.phys
= flash_start
;
139 amazon_map
.virt
= ioremap_nocache(flash_start
, flash_size
);
141 if (!amazon_map
.virt
) {
142 printk(KERN_WARNING
"Failed to ioremap!\n");
146 mymtd
= (struct mtd_info
*) do_map_probe("cfi_probe", &amazon_map
);
148 iounmap(amazon_map
.virt
);
149 printk("probing failed\n");
153 mymtd
->owner
= THIS_MODULE
;
154 parts
= &amazon_partitions
[0];
156 /* Some Samsung devices are containing a 16 MB flash chip with a bigger U-Boot partition. */
157 if(mymtd
->size
== 0x01000000 && mymtd
->erasesize
== 0x00020000) {
158 printk(KERN_INFO
"amazon_mtd: Found big flash chip!\n");
159 amazon_partitions
[0].size
= 0x60000;
160 amazon_partitions
[1].offset
= 0x60000;
161 uimage_size
= find_uImage_size(amazon_partitions
[1].offset
);
162 amazon_partitions
[1].size
= uimage_size
;
163 amazon_partitions
[2].offset
= 0x60000 + uimage_size
;
164 amazon_partitions
[2].size
= mymtd
->size
- amazon_partitions
[2].offset
- mymtd
->erasesize
;
166 printk(KERN_INFO
"amazon_mtd: Found small flash chip!\n");
167 uimage_size
= find_uImage_size(amazon_partitions
[1].offset
);
168 amazon_partitions
[1].size
= uimage_size
;
169 amazon_partitions
[2].offset
= UBOOT_SIZE
+ uimage_size
;
170 amazon_partitions
[2].size
= mymtd
->size
- amazon_partitions
[2].offset
- (2 * mymtd
->erasesize
);
173 add_mtd_partitions(mymtd
, parts
, 3);
175 printk(KERN_INFO
"amazon_mtd: added %s flash with %dMB\n",
176 amazon_map
.name
, mymtd
->size
>> 20);
180 static void __exit
cleanup_amazon_mtd(void)
185 module_init(init_amazon_mtd
);
186 module_exit(cleanup_amazon_mtd
);
188 MODULE_LICENSE("GPL");
189 MODULE_AUTHOR("john crispin blogic@openwrt.org");
190 MODULE_DESCRIPTION("MTD map driver for AMAZON boards");