3e7dc4f58374060727189ffba7d879f2bb8e648b
[openwrt/svn-archive/archive.git] / target / linux / amazon / files / drivers / mtd / maps / amazon.c
1 /*
2 * Handle mapping of the flash memory access routines
3 * on Amazon based devices.
4 *
5 * Copyright(C) 2004 peng.liu@infineon.com
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
19 // copyright 2005 infineon
20
21 // copyright 2007 john crispin <blogic@openwrt.org>
22 // copyright 2007 felix fietkau <nbd@openwrt.org>
23
24 #include <linux/module.h>
25 #include <linux/types.h>
26 #include <linux/kernel.h>
27 #include <asm/io.h>
28
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>
36
37 #define AMAZON_PCI_ARB_CTL_ALT 0xb100205c
38 #define AMAZON_MTD_REG32( addr ) (*(volatile u32 *)(addr))
39
40
41 static struct map_info amazon_map = {
42 .name = "AMAZON_FLASH",
43 .bankwidth = 2,
44 .size = 0x400000,
45 };
46
47 static map_word amazon_read16(struct map_info * map, unsigned long ofs)
48 {
49 map_word temp;
50 ofs ^= 2;
51 temp.x[0] = *((__u16 *) (map->virt + ofs));
52 return temp;
53 }
54
55 static void amazon_write16(struct map_info *map, map_word d, unsigned long adr)
56 {
57 adr ^= 2;
58 *((__u16 *) (map->virt + adr)) = d.x[0];
59 }
60
61 void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
62 {
63 u8 *p;
64 u8 *to_8;
65 ssize_t l = len;
66 from = (unsigned long) (from + map->virt);
67 p = (u8 *) from;
68 to_8 = (u8 *) to;
69 while(len--){
70 *to_8++ = *p++;
71 }
72 }
73
74 void amazon_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
75 {
76 u8 *p = (u8*) from;
77 u8 *to_8;
78 to += (unsigned long) map->virt;
79 to_8 = (u8*)to;
80 while(len--){
81 *p++ = *to_8++;
82 }
83 }
84
85 #define UBOOT_SIZE 0x40000
86
87 static struct mtd_partition amazon_partitions[3] = {
88 {
89 name:"U-Boot", /* U-Boot firmware */
90 offset:0x00000000,
91 size:UBOOT_SIZE , /* 128k */
92 },
93 {
94 name:"kernel", /* firmware */
95 offset:UBOOT_SIZE,
96 size:0x00100000, /* 192K */
97 },
98 {
99 name:"rootfs", /* default partition */
100 offset:0x00200000,
101 size:0x00200000,
102 },
103 };
104
105
106 unsigned long flash_start = 0x13000000;
107 unsigned long flash_size = 0x800000;
108 unsigned long uImage_size = 0x10000d;
109
110 int find_uImage_size(unsigned long start_offset){
111 unsigned long temp;
112
113 printk("trying to find uImage and its size\n");
114 amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4);
115 printk("kernel size is %d \n", temp + 0x40);
116 return temp + 0x40;
117 }
118
119 int __init init_amazon_mtd(void)
120 {
121 int ret = 0;
122 struct mtd_info *mymtd = NULL;
123 struct mtd_partition *parts = NULL;
124
125 *AMAZON_EBU_BUSCON0 = 0x1d7ff;
126
127 amazon_map.read = amazon_read16;
128 amazon_map.write = amazon_write16;
129 amazon_map.copy_from = amazon_copy_from;
130 amazon_map.copy_to = amazon_copy_to;
131
132 amazon_map.phys = flash_start;
133 amazon_map.virt = ioremap_nocache(flash_start, flash_size);
134
135 if (!amazon_map.virt) {
136 printk(KERN_WARNING "Failed to ioremap!\n");
137 return -EIO;
138 }
139
140 mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map);
141 if (!mymtd) {
142 iounmap(amazon_map.virt);
143 printk("probing failed\n");
144 return -ENXIO;
145 }
146
147 mymtd->owner = THIS_MODULE;
148 parts = &amazon_partitions[0];
149 amazon_partitions[2].offset = UBOOT_SIZE + find_uImage_size(amazon_partitions[1].offset);
150 amazon_partitions[1].size = mymtd->size - amazon_partitions[1].offset - (2 * mymtd->erasesize);
151 amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize);
152 add_mtd_partitions(mymtd, parts, 3);
153 return 0;
154 }
155
156 static void __exit cleanup_amazon_mtd(void)
157 {
158 /* FIXME! */
159 }
160
161 module_init(init_amazon_mtd);
162 module_exit(cleanup_amazon_mtd);
163
164 MODULE_LICENSE("GPL");
165 MODULE_AUTHOR("john crispin blogic@openwrt.org");
166 MODULE_DESCRIPTION("MTD map driver for AMAZON boards");