2 * sst28sf040.c: driver for SST28SF040C flash models.
5 * Copyright 2000 Silicon Integrated System Corporation
6 * Copyright 2005 coresystems GmbH <stepan@openbios.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * 4 MEgabit (512K x 8) SuperFlash EEPROM, SST28SF040 data sheet
34 #define AUTO_PG_ERASE1 0x20
35 #define AUTO_PG_ERASE2 0xD0
36 #define AUTO_PGRM 0x10
37 #define CHIP_ERASE 0x30
41 static __inline__ void protect_28sf040(volatile uint8_t *bios)
43 /* ask compiler not to optimize this */
46 tmp = *(volatile uint8_t *)(bios + 0x1823);
47 tmp = *(volatile uint8_t *)(bios + 0x1820);
48 tmp = *(volatile uint8_t *)(bios + 0x1822);
49 tmp = *(volatile uint8_t *)(bios + 0x0418);
50 tmp = *(volatile uint8_t *)(bios + 0x041B);
51 tmp = *(volatile uint8_t *)(bios + 0x0419);
52 tmp = *(volatile uint8_t *)(bios + 0x040A);
55 static __inline__ void unprotect_28sf040(volatile uint8_t *bios)
57 /* ask compiler not to optimize this */
60 tmp = *(volatile uint8_t *)(bios + 0x1823);
61 tmp = *(volatile uint8_t *)(bios + 0x1820);
62 tmp = *(volatile uint8_t *)(bios + 0x1822);
63 tmp = *(volatile uint8_t *)(bios + 0x0418);
64 tmp = *(volatile uint8_t *)(bios + 0x041B);
65 tmp = *(volatile uint8_t *)(bios + 0x0419);
66 tmp = *(volatile uint8_t *)(bios + 0x041A);
69 static __inline__ int erase_sector_28sf040(volatile uint8_t *bios,
70 unsigned long address)
72 *bios = AUTO_PG_ERASE1;
73 *(bios + address) = AUTO_PG_ERASE2;
75 /* wait for Toggle bit ready */
76 toggle_ready_jedec(bios);
81 static __inline__ int write_sector_28sf040(volatile uint8_t *bios,
83 volatile uint8_t *dst,
84 unsigned int page_size)
88 for (i = 0; i < page_size; i++) {
89 /* transfer data from source to destination */
92 /* If the data is 0xFF, don't program it */
95 /*issue AUTO PROGRAM command */
99 /* wait for Toggle bit ready */
100 toggle_ready_jedec(bios);
106 int probe_28sf040(struct flashchip *flash)
108 volatile uint8_t *bios = flash->virtual_memory;
109 uint8_t id1, id2, tmp;
111 /* save the value at the beginning of the Flash */
119 id1 = *(volatile uint8_t *)bios;
121 id2 = *(volatile uint8_t *)(bios + 0x01);
126 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
127 if (id1 == flash->manufacture_id && id2 == flash->model_id)
130 /* if there is no SST28SF040, restore the original value */
135 int erase_28sf040(struct flashchip *flash)
137 volatile uint8_t *bios = flash->virtual_memory;
139 unprotect_28sf040(bios);
142 protect_28sf040(bios);
145 toggle_ready_jedec(bios);
150 int write_28sf040(struct flashchip *flash, uint8_t *buf)
153 int total_size = flash->total_size * 1024;
154 int page_size = flash->page_size;
155 volatile uint8_t *bios = flash->virtual_memory;
157 unprotect_28sf040(bios);
159 printf("Programming Page: ");
160 for (i = 0; i < total_size / page_size; i++) {
161 /* erase the page before programming */
162 erase_sector_28sf040(bios, i * page_size);
164 /* write to the sector */
165 printf("%04d at address: 0x%08x", i, i * page_size);
166 write_sector_28sf040(bios, buf + i * page_size,
167 bios + i * page_size, page_size);
168 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");
172 protect_28sf040(bios);