Move code into *.c files, there's no reason to have it in header files.
[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 #include "m29f400bt.h"
28 #include "debug.h"
29
30 void toggle_ready_m29f400bt(volatile uint8_t *dst)
31 {
32         unsigned int i = 0;
33         uint8_t tmp1, tmp2;
34
35         tmp1 = *dst & 0x40;
36
37         while (i++ < 0xFFFFFF) {
38                 tmp2 = *dst & 0x40;
39                 if (tmp1 == tmp2) {
40                         break;
41                 }
42                 tmp1 = tmp2;
43         }
44 }
45
46 void data_polling_m29f400bt(volatile uint8_t *dst, uint8_t data)
47 {
48         unsigned int i = 0;
49         uint8_t tmp;
50
51         data &= 0x80;
52
53         while (i++ < 0xFFFFFF) {
54                 tmp = *dst & 0x80;
55                 if (tmp == data) {
56                         break;
57                 }
58         }
59 }
60
61 void protect_m29f400bt(volatile uint8_t *bios)
62 {
63         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
64         *(volatile uint8_t *)(bios + 0x555) = 0x55;
65         *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
66
67         usleep(200);
68 }
69
70 void write_page_m29f400bt(volatile uint8_t *bios, uint8_t *src,
71                           volatile uint8_t *dst, int page_size)
72 {
73         int i;
74
75         for (i = 0; i < page_size; i++) {
76                 *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
77                 *(volatile uint8_t *)(bios + 0x555) = 0x55;
78                 *(volatile uint8_t *)(bios + 0xAAA) = 0xA0;
79
80                 /* transfer data from source to destination */
81                 *dst = *src;
82                 //*(volatile char *) (bios) = 0xF0;
83                 //usleep(5);
84                 toggle_ready_m29f400bt(dst);
85                 printf
86                     ("Value in the flash at address %p = %#x, want %#x\n",
87                      (uint8_t *) (dst - bios), *dst, *src);
88                 dst++;
89                 src++;
90         }
91 }
92
93 int probe_m29f400bt(struct flashchip *flash)
94 {
95         volatile uint8_t *bios = flash->virtual_memory;
96         uint8_t id1, id2;
97
98         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
99         *(volatile uint8_t *)(bios + 0x555) = 0x55;
100         *(volatile uint8_t *)(bios + 0xAAA) = 0x90;
101
102         myusec_delay(10);
103
104         id1 = *(volatile uint8_t *)bios;
105         id2 = *(volatile uint8_t *)(bios + 0x02);
106
107         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
108         *(volatile uint8_t *)(bios + 0x555) = 0x55;
109         *(volatile uint8_t *)(bios + 0xAAA) = 0xF0;
110
111         myusec_delay(10);
112
113         printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
114
115         if (id1 == flash->manufacture_id && id2 == flash->model_id)
116                 return 1;
117
118         return 0;
119 }
120
121 int erase_m29f400bt(struct flashchip *flash)
122 {
123         volatile uint8_t *bios = flash->virtual_memory;
124
125         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
126         *(volatile uint8_t *)(bios + 0x555) = 0x55;
127         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
128
129         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
130         *(volatile uint8_t *)(bios + 0x555) = 0x55;
131         *(volatile uint8_t *)(bios + 0xAAA) = 0x10;
132
133         myusec_delay(10);
134         toggle_ready_m29f400bt(bios);
135
136         return (0);
137 }
138
139 int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst)
140 {
141
142         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
143         *(volatile uint8_t *)(bios + 0x555) = 0x55;
144         *(volatile uint8_t *)(bios + 0xAAA) = 0x80;
145
146         *(volatile uint8_t *)(bios + 0xAAA) = 0xAA;
147         *(volatile uint8_t *)(bios + 0x555) = 0x55;
148         //*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
149         *dst = 0x30;
150
151         myusec_delay(10);
152         toggle_ready_m29f400bt(bios);
153
154         return (0);
155 }
156
157 int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
158 {
159         int i;
160         int total_size = flash->total_size * 1024;
161         int page_size = flash->page_size;
162         volatile uint8_t *bios = flash->virtual_memory;
163
164         //erase_m29f400bt (flash);
165         printf("Programming Page:\n ");
166         /*********************************
167         *Pages for M29F400BT:
168         * 16    0x7c000         0x7ffff         TOP
169         *  8    0x7a000         0x7bfff
170         *  8    0x78000         0x79fff
171         * 32    0x70000         0x77fff
172         * 64    0x60000         0x6ffff
173         * 64    0x50000         0x5ffff
174         * 64    0x40000         0x4ffff
175         *---------------------------------
176         * 64    0x30000         0x3ffff
177         * 64    0x20000         0x2ffff
178         * 64    0x10000         0x1ffff
179         * 64    0x00000         0x0ffff         BOTTOM
180         *********************************/
181         printf("total_size/page_size = %d\n", total_size / page_size);
182         for (i = 0; i < (total_size / page_size) - 1; i++) {
183                 printf("%04d at address: 0x%08x\n", i, i * page_size);
184                 block_erase_m29f400bt(bios, bios + i * page_size);
185                 write_page_m29f400bt(bios, buf + i * page_size,
186                                      bios + i * page_size, page_size);
187                 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");
188         }
189
190         printf("%04d at address: 0x%08x\n", 7, 0x70000);
191         block_erase_m29f400bt(bios, bios + 0x70000);
192         write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000, 32 * 1024);
193
194         printf("%04d at address: 0x%08x\n", 8, 0x78000);
195         block_erase_m29f400bt(bios, bios + 0x78000);
196         write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000, 8 * 1024);
197
198         printf("%04d at address: 0x%08x\n", 9, 0x7a000);
199         block_erase_m29f400bt(bios, bios + 0x7a000);
200         write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000, 8 * 1024);
201
202         printf("%04d at address: 0x%08x\n", 10, 0x7c000);
203         block_erase_m29f400bt(bios, bios + 0x7c000);
204         write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000, 16 * 1024);
205
206         printf("\n");
207         //protect_m29f400bt (bios);
208
209         return (0);
210 }
211
212 int write_linuxbios_m29f400bt(struct flashchip *flash, uint8_t *buf)
213 {
214         volatile uint8_t *bios = flash->virtual_memory;
215
216         printf("Programming Page:\n ");
217         /*********************************
218         *Pages for M29F400BT:
219         * 16    0x7c000         0x7ffff         TOP
220         *  8    0x7a000         0x7bfff
221         *  8    0x78000         0x79fff
222         * 32    0x70000         0x77fff
223         * 64    0x60000         0x6ffff
224         * 64    0x50000         0x5ffff
225         * 64    0x40000         0x4ffff
226         *---------------------------------
227         * 64    0x30000         0x3ffff
228         * 64    0x20000         0x2ffff
229         * 64    0x10000         0x1ffff
230         * 64    0x00000         0x0ffff         BOTTOM
231         *********************************/
232         printf("%04d at address: 0x%08x\n", 7, 0x00000);
233         block_erase_m29f400bt(bios, bios + 0x00000);
234         write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000, 64 * 1024);
235
236         printf("%04d at address: 0x%08x\n", 7, 0x10000);
237         block_erase_m29f400bt(bios, bios + 0x10000);
238         write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000, 64 * 1024);
239
240         printf("%04d at address: 0x%08x\n", 7, 0x20000);
241         block_erase_m29f400bt(bios, bios + 0x20000);
242         write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000, 64 * 1024);
243
244         printf("%04d at address: 0x%08x\n", 7, 0x30000);
245         block_erase_m29f400bt(bios, bios + 0x30000);
246         write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000, 64 * 1024);
247
248         printf("\n");
249         //protect_m29f400bt (bios);
250
251         return (0);
252 }