Drop a bunch of useless header files, merge them into flash.h.
[coreboot.git] / util / flashrom / m29f400bt.c
1 /*
2  * m29f400bt.c: driver for programming JEDEC standard flash parts
3  *
4  *
5  * Copyright 2000 Silicon Integrated System Corporation
6  *
7  *      This program is free software; you can redistribute it and/or modify
8  *      it under the terms of the GNU General Public License as published by
9  *      the Free Software Foundation; either version 2 of the License, or
10  *      (at your option) any later version.
11  *
12  *      This program is distributed in the hope that it will be useful,
13  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *      GNU General Public License for more details.
16  *
17  *      You should have received a copy of the GNU General Public License
18  *      along with this program; if not, write to the Free Software
19  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  *
22  * Reference:
23  *
24  */
25
26 #include "flash.h"
27
28 void toggle_ready_m29f400bt(volatile uint8_t *dst)
29 {
30         unsigned int i = 0;
31         uint8_t tmp1, tmp2;
32
33         tmp1 = *dst & 0x40;
34
35         while (i++ < 0xFFFFFF) {
36                 tmp2 = *dst & 0x40;
37                 if (tmp1 == tmp2) {
38                         break;
39                 }
40                 tmp1 = tmp2;
41         }
42 }
43
44 void data_polling_m29f400bt(volatile uint8_t *dst, uint8_t data)
45 {
46         unsigned int i = 0;
47         uint8_t tmp;
48
49         data &= 0x80;
50
51         while (i++ < 0xFFFFFF) {
52                 tmp = *dst & 0x80;
53                 if (tmp == data) {
54                         break;
55                 }
56         }
57 }
58
59 void protect_m29f400bt(volatile uint8_t *bios)
60 {
61         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
62         *(volatile uint8_t *)(bios + 0x555) = 0x55;
63         *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
64
65         usleep(200);
66 }
67
68 void write_page_m29f400bt(volatile uint8_t *bios, uint8_t *src,
69                           volatile uint8_t *dst, int page_size)
70 {
71         int i;
72
73         for (i = 0; i < page_size; i++) {
74                 *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
75                 *(volatile uint8_t *)(bios + 0x555) = 0x55;
76                 *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
77
78                 /* transfer data from source to destination */
79                 *dst = *src;
80                 //*(volatile char *) (bios) = 0xF0;
81                 //usleep(5);
82                 toggle_ready_m29f400bt(dst);
83                 printf
84                     ("Value in the flash at address %p = %#x, want %#x\n",
85                      (uint8_t *) (dst - bios), *dst, *src);
86                 dst++;
87                 src++;
88         }
89 }
90
91 int probe_m29f400bt(struct flashchip *flash)
92 {
93         volatile uint8_t *bios = flash->virtual_memory;
94         uint8_t id1, id2;
95
96         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
97         *(volatile uint8_t *)(bios + 0x555) = 0x55;
98         *(volatile uint8_t *)(bios + 0xAAA) = 0x90;
99
100         myusec_delay(10);
101
102         id1 = *(volatile uint8_t *)bios;
103         id2 = *(volatile uint8_t *)(bios + 0x02);
104
105         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
106         *(volatile uint8_t *)(bios + 0x555) = 0x55;
107         *(volatile uint8_t *)(bios + 0xAAA) = 0xF0;
108
109         myusec_delay(10);
110
111         printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
112
113         if (id1 == flash->manufacture_id && id2 == flash->model_id)
114                 return 1;
115
116         return 0;
117 }
118
119 int erase_m29f400bt(struct flashchip *flash)
120 {
121         volatile uint8_t *bios = flash->virtual_memory;
122
123         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
124         *(volatile uint8_t *)(bios + 0x555) = 0x55;
125         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
126
127         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
128         *(volatile uint8_t *)(bios + 0x555) = 0x55;
129         *(volatile uint8_t *)(bios + 0xAAA) = 0x10;
130
131         myusec_delay(10);
132         toggle_ready_m29f400bt(bios);
133
134         return (0);
135 }
136
137 int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst)
138 {
139
140         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
141         *(volatile uint8_t *)(bios + 0x555) = 0x55;
142         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
143
144         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
145         *(volatile uint8_t *)(bios + 0x555) = 0x55;
146         //*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
147         *dst = 0x30;
148
149         myusec_delay(10);
150         toggle_ready_m29f400bt(bios);
151
152         return (0);
153 }
154
155 int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
156 {
157         int i;
158         int total_size = flash->total_size * 1024;
159         int page_size = flash->page_size;
160         volatile uint8_t *bios = flash->virtual_memory;
161
162         //erase_m29f400bt (flash);
163         printf("Programming Page:\n ");
164         /*********************************
165         *Pages for M29F400BT:
166         * 16    0x7c000         0x7ffff         TOP
167         *  8    0x7a000         0x7bfff
168         *  8    0x78000         0x79fff
169         * 32    0x70000         0x77fff
170         * 64    0x60000         0x6ffff
171         * 64    0x50000         0x5ffff
172         * 64    0x40000         0x4ffff
173         *---------------------------------
174         * 64    0x30000         0x3ffff
175         * 64    0x20000         0x2ffff
176         * 64    0x10000         0x1ffff
177         * 64    0x00000         0x0ffff         BOTTOM
178         *********************************/
179         printf("total_size/page_size = %d\n", total_size / page_size);
180         for (i = 0; i < (total_size / page_size) - 1; i++) {
181                 printf("%04d at address: 0x%08x\n", i, i * page_size);
182                 block_erase_m29f400bt(bios, bios + i * page_size);
183                 write_page_m29f400bt(bios, buf + i * page_size,
184                                      bios + i * page_size, page_size);
185                 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");
186         }
187
188         printf("%04d at address: 0x%08x\n", 7, 0x70000);
189         block_erase_m29f400bt(bios, bios + 0x70000);
190         write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
191
192         printf("%04d at address: 0x%08x\n", 8, 0x78000);
193         block_erase_m29f400bt(bios, bios + 0x78000);
194         write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
195
196         printf("%04d at address: 0x%08x\n", 9, 0x7a000);
197         block_erase_m29f400bt(bios, bios + 0x7a000);
198         write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
199
200         printf("%04d at address: 0x%08x\n", 10, 0x7c000);
201         block_erase_m29f400bt(bios, bios + 0x7c000);
202         write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
203
204         printf("\n");
205         //protect_m29f400bt (bios);
206
207         return (0);
208 }
209
210 int write_linuxbios_m29f400bt(struct flashchip *flash, uint8_t *buf)
211 {
212         volatile uint8_t *bios = flash->virtual_memory;
213
214         printf("Programming Page:\n ");
215         /*********************************
216         *Pages for M29F400BT:
217         * 16    0x7c000         0x7ffff         TOP
218         *  8    0x7a000         0x7bfff
219         *  8    0x78000         0x79fff
220         * 32    0x70000         0x77fff
221         * 64    0x60000         0x6ffff
222         * 64    0x50000         0x5ffff
223         * 64    0x40000         0x4ffff
224         *---------------------------------
225         * 64    0x30000         0x3ffff
226         * 64    0x20000         0x2ffff
227         * 64    0x10000         0x1ffff
228         * 64    0x00000         0x0ffff         BOTTOM
229         *********************************/
230         printf("%04d at address: 0x%08x\n", 7, 0x00000);
231         block_erase_m29f400bt(bios, bios + 0x00000);
232         write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
233
234         printf("%04d at address: 0x%08x\n", 7, 0x10000);
235         block_erase_m29f400bt(bios, bios + 0x10000);
236         write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
237
238         printf("%04d at address: 0x%08x\n", 7, 0x20000);
239         block_erase_m29f400bt(bios, bios + 0x20000);
240         write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
241
242         printf("%04d at address: 0x%08x\n", 7, 0x30000);
243         block_erase_m29f400bt(bios, bios + 0x30000);
244         write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
245
246         printf("\n");
247         //protect_m29f400bt (bios);
248
249         return (0);
250 }