b45486157de51d29186f6f310926b7506b904405
[openwrt.git] / target / linux / linux-2.4 / patches / ar7 / 001-flash_map.patch
1 diff -urN linux-2.4.30/drivers/mtd/maps/Config.in linux-2.4.30.dev/drivers/mtd/maps/Config.in
2 --- linux-2.4.30/drivers/mtd/maps/Config.in     2005-06-14 19:31:49.000000000 +0200
3 +++ linux-2.4.30.dev/drivers/mtd/maps/Config.in 2005-06-14 15:36:59.000000000 +0200
4 @@ -48,6 +48,21 @@
5  fi
6  
7  if [ "$CONFIG_MIPS" = "y" ]; then
8 +    if [ "$CONFIG_AR7" = "y" ]; then
9 +      dep_tristate '  Flash chip mapping on Texas Instruments AR7' CONFIG_MTD_AVALANCHE $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
10 +      dep_bool     '    Use defaults for Texas Instruments AR7' CONFIG_MTD_AVALANCHE_DEFAULTS $CONFIG_MTD_AVALANCHE
11 +      if [ "$CONFIG_MTD_AVALANCHE" = "y" -o "$CONFIG_MTD_AVALANCHE" = "m" ]; then
12 +         if [ "$CONFIG_MTD_AVALANCHE_DEFAULTS" = "y" ]; then
13 +            define_hex CONFIG_MTD_AVALANCHE_START 0x10000000
14 +            define_hex CONFIG_MTD_AVALANCHE_LEN 0x400000
15 +            define_int CONFIG_MTD_AVALANCHE_BUSWIDTH 2
16 +         else
17 +            hex '      Physical start address of flash mapping' CONFIG_MTD_AVALANCHE_START 0x10000000
18 +            hex '      Physical length of flash mapping' CONFIG_MTD_AVALANCHE_LEN 0x400000
19 +            int '      Bus width in octets' CONFIG_MTD_AVALANCHE_BUSWIDTH 2
20 +         fi
21 +      fi
22 +   fi
23     dep_tristate '  Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
24     dep_tristate '  Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
25     dep_tristate '  Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
26 diff -urN linux-2.4.30/drivers/mtd/maps/Makefile linux-2.4.30.dev/drivers/mtd/maps/Makefile
27 --- linux-2.4.30/drivers/mtd/maps/Makefile      2005-06-14 19:31:49.000000000 +0200
28 +++ linux-2.4.30.dev/drivers/mtd/maps/Makefile  2005-06-14 15:36:59.000000000 +0200
29 @@ -10,6 +10,7 @@
30  endif
31  
32  # Chip mappings
33 +obj-$(CONFIG_MTD_AVALANCHE)    += ar7-flash.o
34  obj-$(CONFIG_MTD_CDB89712)     += cdb89712.o
35  obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
36  obj-$(CONFIG_MTD_CFI_FLAGADM)  += cfi_flagadm.o
37 diff -urN linux-2.4.30/drivers/mtd/maps/ar7-flash.c linux-2.4.30.dev/drivers/mtd/maps/ar7-flash.c
38 --- linux-2.4.30/drivers/mtd/maps/ar7-flash.c   1970-01-01 01:00:00.000000000 +0100
39 +++ linux-2.4.30.dev/drivers/mtd/maps/ar7-flash.c       2005-06-14 22:42:23.000000000 +0200
40 @@ -0,0 +1,245 @@
41 +/*
42 + * $Id$
43 + *
44 + * Normal mappings of chips in physical memory
45 + */
46 +
47 +#include <linux/module.h>
48 +#include <linux/types.h>
49 +#include <linux/kernel.h>
50 +#include <asm/io.h>
51 +#include <linux/mtd/mtd.h>
52 +#include <linux/mtd/map.h>
53 +#include <linux/config.h>
54 +#include <linux/mtd/partitions.h>
55 +#include "trxhdr.h"
56 +
57 +#define WINDOW_ADDR CONFIG_MTD_AVALANCHE_START
58 +#define WINDOW_SIZE CONFIG_MTD_AVALANCHE_LEN
59 +#define BUSWIDTH CONFIG_MTD_AVALANCHE_BUSWIDTH
60 +
61 +#include <asm/mips-boards/prom.h>
62 +extern char *prom_getenv(char *name);
63 +
64 +static int create_mtd_partitions(void);
65 +static void __exit avalanche_mtd_cleanup(void);
66 +       
67 +/* avalanche__partition_info gives details on the logical partitions that splits
68 + * the flash device into. If the size if zero we use up to the end of
69 + * the device. */
70 +#define MAX_NUM_PARTITIONS 5
71 +static struct mtd_partition avalanche_partition_info[MAX_NUM_PARTITIONS];
72 +static int num_of_partitions = 0;
73 +
74 +static struct mtd_info *avalanche_mtd_info;
75 +
76 +int avalanche_mtd_ready=0;
77 +
78 +__u8 avalanche_read8(struct map_info *map, unsigned long ofs)
79 +{
80 +       return __raw_readb(map->map_priv_1 + ofs);
81 +}
82 +
83 +__u16 avalanche_read16(struct map_info *map, unsigned long ofs)
84 +{
85 +       return __raw_readw(map->map_priv_1 + ofs);
86 +}
87 +
88 +__u32 avalanche_read32(struct map_info *map, unsigned long ofs)
89 +{
90 +       return __raw_readl(map->map_priv_1 + ofs);
91 +}
92 +
93 +void avalanche_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
94 +{
95 +       memcpy_fromio(to, map->map_priv_1 + from, len);
96 +}
97 +
98 +void avalanche_write8(struct map_info *map, __u8 d, unsigned long adr)
99 +{
100 +       __raw_writeb(d, map->map_priv_1 + adr);
101 +       mb();
102 +}
103 +
104 +void avalanche_write16(struct map_info *map, __u16 d, unsigned long adr)
105 +{
106 +       __raw_writew(d, map->map_priv_1 + adr);
107 +       mb();
108 +}
109 +
110 +void avalanche_write32(struct map_info *map, __u32 d, unsigned long adr)
111 +{
112 +       __raw_writel(d, map->map_priv_1 + adr);
113 +       mb();
114 +}
115 +
116 +void avalanche_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
117 +{
118 +       memcpy_toio(map->map_priv_1 + to, from, len);
119 +}
120 +
121 +struct map_info avalanche_map = {
122 +       name: "Physically mapped flash",
123 +       size: WINDOW_SIZE,
124 +       buswidth: BUSWIDTH,
125 +       read8: avalanche_read8,
126 +       read16: avalanche_read16,
127 +       read32: avalanche_read32,
128 +       copy_from: avalanche_copy_from,
129 +       write8: avalanche_write8,
130 +       write16: avalanche_write16,
131 +       write32: avalanche_write32,
132 +       copy_to: avalanche_copy_to
133 +};
134 +
135 +int __init avalanche_mtd_init(void)
136 +{
137 +               printk(KERN_NOTICE "avalanche flash device: 0x%lx at 0x%lx.\n", (unsigned long)WINDOW_SIZE, (unsigned long)WINDOW_ADDR);
138 +       avalanche_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
139 +
140 +       if (!avalanche_map.map_priv_1) {
141 +               printk("Failed to ioremap\n");
142 +               return -EIO;
143 +       }
144 +       
145 +       avalanche_mtd_info = do_map_probe("cfi_probe", &avalanche_map);
146 +       if (!avalanche_mtd_info)
147 +       {
148 +               avalanche_mtd_cleanup();
149 +               return -ENXIO;
150 +       }
151 +       
152 +       avalanche_mtd_info->module = THIS_MODULE;
153 +
154 +       if (!create_mtd_partitions())
155 +               add_mtd_device(avalanche_mtd_info);
156 +       else            
157 +               add_mtd_partitions(avalanche_mtd_info, avalanche_partition_info, num_of_partitions);
158 +
159 +       avalanche_mtd_ready=1;
160 +       
161 +       return 0;
162 +}
163 +
164 +static char *strdup(char *str)
165 +{
166 +       int n = strlen(str)+1;
167 +       char *s = kmalloc(n, GFP_KERNEL);
168 +       if (!s) return NULL;
169 +       return strcpy(s, str);
170 +}
171 +
172 +
173 +static int create_mtd_partitions(void)
174 +{
175 +       unsigned int offset;
176 +       unsigned int size;
177 +       unsigned int found;
178 +       unsigned char *flash_base;
179 +       unsigned char *flash_end;
180 +       struct trx_header hdr;
181 +       char *env_ptr;
182 +       char *base_ptr;
183 +       char *end_ptr;
184 +
185 +       do {
186 +               char    env_name[20];
187 +
188 +               found = 0;
189 +
190 +               /* get base and end addresses of flash file system from environment */
191 +               sprintf(env_name, "mtd%1u", num_of_partitions);
192 +               printk("Looking for mtd device :%s:\n", env_name);
193 +
194 +               env_ptr = prom_getenv(env_name);
195 +               if(env_ptr == NULL) {
196 +                       /* No more partitions to find */
197 +                       break;
198 +               }
199 +
200 +               /* Extract the start and stop addresses of the partition */
201 +               base_ptr = strtok(env_ptr, ",");
202 +               end_ptr = strtok(NULL, ",");
203 +               if ((base_ptr == NULL) || (end_ptr == NULL)) {  
204 +                       printk("JFFS2 ERROR: Invalid %s start,end.\n", env_name);
205 +                       break;
206 +               }
207 +
208 +               flash_base = (unsigned char*) simple_strtol(base_ptr, NULL, 0);
209 +               flash_end = (unsigned char*) simple_strtol(end_ptr, NULL, 0);
210 +               if((!flash_base) || (!flash_end)) {
211 +                       printk("JFFS2 ERROR: Invalid %s start,end.\n", env_name);
212 +                       break;
213 +               }
214 +
215 +               offset = virt_to_bus(flash_base) - WINDOW_ADDR;
216 +               size = flash_end - flash_base;
217 +               printk("Found a %s image (0x%x), with size (0x%x).\n",env_name, offset, size);
218 +
219 +               /* Setup the partition info. We duplicate the env_name for the partiton name */
220 +               avalanche_partition_info[num_of_partitions].offset = offset;
221 +               avalanche_partition_info[num_of_partitions].size = size;
222 +               avalanche_partition_info[num_of_partitions].mask_flags = 0;
223 +               
224 +               switch (num_of_partitions ) {
225 +                       case 0:
226 +                               avalanche_partition_info[num_of_partitions].name = strdup("rootfs");
227 +                               avalanche_copy_from(&avalanche_map, &hdr, offset, sizeof(hdr));
228 +                               if (hdr.magic == TRX_MAGIC) {
229 +                                       printk("TRX partition detected. First offset: %08x\n", hdr.offsets[0]);
230 +                                       avalanche_partition_info[num_of_partitions].offset += hdr.offsets[0];
231 +                                       avalanche_partition_info[num_of_partitions].size -= hdr.offsets[0];
232 +                               } else {
233 +                                       printk("No TRX partition detected\n");
234 +                               }
235 +                               break;
236 +                               
237 +                       case 1:
238 +                               avalanche_partition_info[num_of_partitions].name = strdup("linux");
239 +                               break;
240 +                               
241 +                       case 2:
242 +                               avalanche_partition_info[num_of_partitions].name = strdup("adam2");
243 +                               break;
244 +                               
245 +                       case 3:
246 +                               avalanche_partition_info[num_of_partitions].name = strdup("config");
247 +                               break;
248 +                       
249 +                       case 4:
250 +                               avalanche_partition_info[num_of_partitions].name = strdup("firmware");
251 +                               break;
252 +
253 +                       default:
254 +                               avalanche_partition_info[num_of_partitions].name = strdup(env_name);
255 +                               break;
256 +               }
257 +               
258 +               num_of_partitions++;
259 +       } while (num_of_partitions < MAX_NUM_PARTITIONS);
260 +
261 +       return num_of_partitions;
262 +}
263 +
264 +static void __exit avalanche_mtd_cleanup(void)
265 +{
266 +       avalanche_mtd_ready=0;
267 +
268 +       if (avalanche_mtd_info) {
269 +               del_mtd_partitions(avalanche_mtd_info);
270 +               del_mtd_device(avalanche_mtd_info);
271 +               map_destroy(avalanche_mtd_info);
272 +       }
273 +
274 +       if (avalanche_map.map_priv_1) {
275 +               iounmap((void *)avalanche_map.map_priv_1);
276 +               avalanche_map.map_priv_1 = 0;
277 +       }
278 +}
279 +
280 +module_init(avalanche_mtd_init);
281 +module_exit(avalanche_mtd_cleanup);
282 +
283 +MODULE_LICENSE("GPL");
284 +MODULE_AUTHOR("Snehaprabha Narnakaje");
285 +MODULE_DESCRIPTION("Avalanche CFI map driver");
286 diff -urN linux-2.4.30/drivers/mtd/maps/trxhdr.h linux-2.4.30.dev/drivers/mtd/maps/trxhdr.h
287 --- linux-2.4.30/drivers/mtd/maps/trxhdr.h      1970-01-01 01:00:00.000000000 +0100
288 +++ linux-2.4.30.dev/drivers/mtd/maps/trxhdr.h  2005-06-14 21:57:04.000000000 +0200
289 @@ -0,0 +1,29 @@
290 +/*
291 + * TRX image file header format.
292 + *
293 + * Copyright 2005, Broadcom Corporation
294 + * All Rights Reserved.
295 + * 
296 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
297 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
298 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
299 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
300 + *
301 + * $Id$
302 + */ 
303 +
304 +
305 +#define TRX_MAGIC      0x30524448      /* "HDR0" */
306 +#define TRX_VERSION    1
307 +#define TRX_MAX_LEN    0x3A0000
308 +#define TRX_NO_HEADER  1               /* Do not write TRX header */   
309 +#define TRX_GZ_FILES   0x2     /* Contains up to TRX_MAX_OFFSET individual gzip files */
310 +#define TRX_MAX_OFFSET 3
311 +
312 +struct trx_header {
313 +       __u32 magic;            /* "HDR0" */
314 +       __u32 len;              /* Length of file including header */
315 +       __u32 crc32;            /* 32-bit CRC from flag_version to end of file */
316 +       __u32 flag_version;     /* 0:15 flags, 16:31 version */
317 +       __u32 offsets[TRX_MAX_OFFSET];  /* Offsets of partitions from start of header */
318 +};