2 * jedec.c: driver for programming JEDEC standard flash parts
5 * Copyright 2000 Silicon Integrated System Corporation
6 * Copyright 2006 Giampiero Giancipoli <gianci@email.it>
7 * Copyright 2006 coresystems GmbH <info@coresystems.de>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #define MAX_REFLASH_TRIES 0x10
34 void toggle_ready_jedec(volatile uint8_t *dst)
41 while (i++ < 0xFFFFFFF) {
50 void data_polling_jedec(volatile uint8_t *dst, uint8_t data)
57 while (i++ < 0xFFFFFFF) {
65 void unprotect_jedec(volatile uint8_t *bios)
67 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
68 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
69 *(volatile uint8_t *)(bios + 0x5555) = 0x80;
70 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
71 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
72 *(volatile uint8_t *)(bios + 0x5555) = 0x20;
77 void protect_jedec(volatile uint8_t *bios)
79 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
80 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
81 *(volatile uint8_t *)(bios + 0x5555) = 0xA0;
86 int probe_jedec(struct flashchip *flash)
88 volatile uint8_t *bios = flash->virtual_memory;
91 /* Issue JEDEC Product ID Entry command */
92 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
94 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
96 *(volatile uint8_t *)(bios + 0x5555) = 0x90;
100 id1 = *(volatile uint8_t *)bios;
101 id2 = *(volatile uint8_t *)(bios + 0x01);
103 /* Issue JEDEC Product ID Exit command */
104 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
106 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
108 *(volatile uint8_t *)(bios + 0x5555) = 0xF0;
111 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
112 if (id1 == flash->manufacture_id && id2 == flash->model_id)
118 int erase_sector_jedec(volatile uint8_t *bios, unsigned int page)
120 /* Issue the Sector Erase command */
121 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
123 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
125 *(volatile uint8_t *)(bios + 0x5555) = 0x80;
128 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
130 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
132 *(volatile uint8_t *)(bios + page) = 0x30;
135 /* wait for Toggle bit ready */
136 toggle_ready_jedec(bios);
141 int erase_block_jedec(volatile uint8_t *bios, unsigned int block)
143 /* Issue the Sector Erase command */
144 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
146 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
148 *(volatile uint8_t *)(bios + 0x5555) = 0x80;
151 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
153 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
155 *(volatile uint8_t *)(bios + block) = 0x50;
158 /* wait for Toggle bit ready */
159 toggle_ready_jedec(bios);
164 int erase_chip_jedec(struct flashchip *flash)
166 volatile uint8_t *bios = flash->virtual_memory;
168 /* Issue the JEDEC Chip Erase command */
169 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
171 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
173 *(volatile uint8_t *)(bios + 0x5555) = 0x80;
176 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
178 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
180 *(volatile uint8_t *)(bios + 0x5555) = 0x10;
183 toggle_ready_jedec(bios);
188 int write_page_write_jedec(volatile uint8_t *bios, uint8_t *src,
189 volatile uint8_t *dst, int page_size)
191 int i, tried = 0, start_index = 0, ok;
192 volatile uint8_t *d = dst;
196 /* Issue JEDEC Data Unprotect comand */
197 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
198 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
199 *(volatile uint8_t *)(bios + 0x5555) = 0xA0;
201 /* transfer data from source to destination */
202 for (i = start_index; i < page_size; i++) {
203 /* If the data is 0xFF, don't program it */
210 toggle_ready_jedec(dst - 1);
215 for (i = 0; i < page_size; i++) {
224 if (!ok && tried++ < MAX_REFLASH_TRIES) {
229 fprintf(stderr, " page %d failed!\n",
230 (unsigned int)(d - bios) / page_size);
235 int write_byte_program_jedec(volatile uint8_t *bios, uint8_t *src,
236 volatile uint8_t *dst)
238 int tried = 0, ok = 1;
240 /* If the data is 0xFF, don't program it */
246 /* Issue JEDEC Byte Program command */
247 *(volatile uint8_t *)(bios + 0x5555) = 0xAA;
248 *(volatile uint8_t *)(bios + 0x2AAA) = 0x55;
249 *(volatile uint8_t *)(bios + 0x5555) = 0xA0;
251 /* transfer data from source to destination */
253 toggle_ready_jedec(bios);
255 if (*dst != *src && tried++ < MAX_REFLASH_TRIES) {
259 if (tried >= MAX_REFLASH_TRIES)
265 int write_sector_jedec(volatile uint8_t *bios, uint8_t *src,
266 volatile uint8_t *dst, unsigned int page_size)
270 for (i = 0; i < page_size; i++) {
271 write_byte_program_jedec(bios, src, dst);
278 int write_jedec(struct flashchip *flash, uint8_t *buf)
281 int total_size = flash->total_size * 1024;
282 int page_size = flash->page_size;
283 volatile uint8_t *bios = flash->virtual_memory;
285 erase_chip_jedec(flash);
286 // dumb check if erase was successful.
287 for (i = 0; i < total_size; i++) {
288 if (bios[i] != (uint8_t) 0xff) {
289 printf("ERASE FAILED\n");
294 printf("Programming Page: ");
295 for (i = 0; i < total_size / page_size; i++) {
296 printf("%04d at address: 0x%08x", i, i * page_size);
297 write_page_write_jedec(bios, buf + i * page_size,
298 bios + i * page_size, page_size);
299 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");