2 /* Copyright 2000 AG Electronics Ltd. */
3 /* This code is distributed without warranty under the GPL v2 (see COPYING) */
5 #include <console/console.h>
17 static const char *identify_amd (struct flash_device *flash_device);
18 static int erase_flash_amd800 (void *data, unsigned offset, unsigned length);
19 static int program_flash_amd800 (void *data, unsigned offset, const void *source,
21 static uint8_t read_byte_amd800(void *data, unsigned offset);
23 static flash_fn fn_amd800 = {
32 const char *identify_amd (struct flash_device *flash_device)
34 struct data_amd800 *d800 = flash_device->data;
38 volatile unsigned char *flash =
40 (volatile unsigned char *) d800->base;
44 *(flash + 0xaaa * d800->spacing) = 0xaa;
45 *(flash + 0x555 * d800->spacing) = 0x55;
46 *(flash + 0xaaa * d800->spacing) = 0x90;
47 type = *(flash + 2 * d800->spacing);
50 if ((id == 1 || id == 0x20) && type == 0x5b)
53 d800->tag = "Am29LV800BB";
54 flash_device->base = d800->base;
55 flash_device->size = 1024*1024;
56 flash_device->erase_size = 64*1024;
57 flash_device->store_size = 1;
61 printk_info("Unknown flash ID: 0x%02x 0x%02x\n", id, type);
67 int erase_flash_amd800 (void *data, unsigned offset, unsigned length)
69 struct data_amd800 *d800 = data;
70 volatile unsigned char *flash = (volatile unsigned char *) d800->base;
71 volatile unsigned char *flash_aaa = flash + 0xaaa * d800->spacing;
72 volatile unsigned char *flash_555 = flash + 0x555 * d800->spacing;
76 printk_info("Erase from 0x%08x to 0x%08x\n", offset, offset + length);
77 *flash_aaa = 0xAA; // Chip Erase
87 if (id & 0xA0) // DQ7 or DQ5 set: done or error
89 printk_info("%4d\b\b\b\b", cs);
92 *flash_aaa = 0xF0; // In case of error
94 printk_info("\b\b\b\b \b\b\b\b");
97 printk_info("Could not erase flash, timeout.\n");
100 else if ((id & 0x80) == 0)
102 printk_info("Could not erase flash, status=%02x.\n", id);
105 printk_info("Flash erased\n");
109 int init_flash_amd800 (char *tag, unsigned base, unsigned spacing)
111 struct data_amd800 *data = malloc (sizeof (struct data_amd800));
116 data->spacing = spacing;
118 if (register_flash_device (&fn_amd800, tag, data) < 0)
129 int program_flash_amd800 (void *data, unsigned offset, const void *source,
132 struct data_amd800 *d800 = data;
133 volatile unsigned char *flash = (volatile unsigned char *) d800->base;
134 volatile unsigned char *flash_aaa = flash + 0xaaa * d800->spacing;
135 volatile unsigned char *flash_555 = flash + 0x555 * d800->spacing;
142 printk_info("Program from 0x%08x to 0x%08x\n", offset, offset + length);
143 printk_info("Data at %p\n", source);
145 *flash_aaa = 0xAA; // Unlock Bypass
149 s = (unsigned char *) source;
150 d = flash + offset * d800->spacing;
153 while (cs > 0 && !errs)
155 *flash = 0xA0; // Unlock Bypass Program
156 *d = *s; // Program data
161 if ((id & 0x80) == (*s & 0x80)) // DQ7 right? => program done
164 { // DQ5 set? => maybe errors
166 if ((id & 0x80) != (*s & 0x80))
174 // PRINT("Set %08lx = %02x\n", d, *d);
181 *flash = 0x90; // Unlock Bypass Program Reset
187 printk_info("FAIL: Status=%02x Address=%p.\n", id, d - d800->spacing);
190 printk_info("OK.\n");
193 // Step 4: Verify the flash.
195 printk_info(" Verifying flash : ...");
197 s = (unsigned char *) source;
198 d = flash + offset * d800->spacing;
199 for (cs = 0; cs < length; cs++)
204 printk_info("ERROR: Addr: %08p, PCI: %02x Lcl: %02x.\n",
213 printk_info("OK.\n");
216 printk_info(" FAIL: %d errors.\n", errs);
223 uint8_t read_byte_amd800 (void *data, unsigned offset)
225 struct data_amd800 *d800 = data;
226 volatile unsigned char *flash = (volatile unsigned char *) d800->base;
227 return *(flash + offset * d800->spacing);