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
32 #define AUTO_PG_ERASE1 0x20
33 #define AUTO_PG_ERASE2 0xD0
34 #define AUTO_PGRM 0x10
35 #define CHIP_ERASE 0x30
39 static __inline__ void protect_28sf040(volatile uint8_t *bios)
41 /* ask compiler not to optimize this */
44 tmp = *(volatile uint8_t *)(bios + 0x1823);
45 tmp = *(volatile uint8_t *)(bios + 0x1820);
46 tmp = *(volatile uint8_t *)(bios + 0x1822);
47 tmp = *(volatile uint8_t *)(bios + 0x0418);
48 tmp = *(volatile uint8_t *)(bios + 0x041B);
49 tmp = *(volatile uint8_t *)(bios + 0x0419);
50 tmp = *(volatile uint8_t *)(bios + 0x040A);
53 static __inline__ void unprotect_28sf040(volatile uint8_t *bios)
55 /* ask compiler not to optimize this */
58 tmp = *(volatile uint8_t *)(bios + 0x1823);
59 tmp = *(volatile uint8_t *)(bios + 0x1820);
60 tmp = *(volatile uint8_t *)(bios + 0x1822);
61 tmp = *(volatile uint8_t *)(bios + 0x0418);
62 tmp = *(volatile uint8_t *)(bios + 0x041B);
63 tmp = *(volatile uint8_t *)(bios + 0x0419);
64 tmp = *(volatile uint8_t *)(bios + 0x041A);
67 static __inline__ int erase_sector_28sf040(volatile uint8_t *bios,
68 unsigned long address)
70 *bios = AUTO_PG_ERASE1;
71 *(bios + address) = AUTO_PG_ERASE2;
73 /* wait for Toggle bit ready */
74 toggle_ready_jedec(bios);
79 static __inline__ int write_sector_28sf040(volatile uint8_t *bios,
81 volatile uint8_t *dst,
82 unsigned int page_size)
86 for (i = 0; i < page_size; i++) {
87 /* transfer data from source to destination */
90 /* If the data is 0xFF, don't program it */
93 /*issue AUTO PROGRAM command */
97 /* wait for Toggle bit ready */
98 toggle_ready_jedec(bios);
104 int probe_28sf040(struct flashchip *flash)
106 volatile uint8_t *bios = flash->virtual_memory;
114 id1 = *(volatile uint8_t *)bios;
116 id2 = *(volatile uint8_t *)(bios + 0x01);
121 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
122 if (id1 == flash->manufacture_id && id2 == flash->model_id)
128 int erase_28sf040(struct flashchip *flash)
130 volatile uint8_t *bios = flash->virtual_memory;
132 unprotect_28sf040(bios);
135 protect_28sf040(bios);
138 toggle_ready_jedec(bios);
143 int write_28sf040(struct flashchip *flash, uint8_t *buf)
146 int total_size = flash->total_size * 1024;
147 int page_size = flash->page_size;
148 volatile uint8_t *bios = flash->virtual_memory;
150 unprotect_28sf040(bios);
152 printf("Programming Page: ");
153 for (i = 0; i < total_size / page_size; i++) {
154 /* erase the page before programming */
155 erase_sector_28sf040(bios, i * page_size);
157 /* write to the sector */
158 printf("%04d at address: 0x%08x", i, i * page_size);
159 write_sector_28sf040(bios, buf + i * page_size,
160 bios + i * page_size, page_size);
161 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");
165 protect_28sf040(bios);