flasrom update from Stefan, resovle issue 21
[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  * $Id$
25  */
26
27 #include "flash.h"
28 #include "m29f400bt.h"
29 #include "debug.h"
30
31 int probe_m29f400bt(struct flashchip *flash)
32 {
33         volatile uint8_t *bios = flash->virt_addr;
34         uint8_t id1, id2;
35
36         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
37         *(volatile uint8_t *) (bios + 0x555) = 0x55;
38         *(volatile uint8_t *) (bios + 0xAAA) = 0x90;
39
40         myusec_delay(10);
41
42         id1 = *(volatile uint8_t *) bios;
43         id2 = *(volatile uint8_t *) (bios + 0x02);
44
45         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
46         *(volatile uint8_t *) (bios + 0x555) = 0x55;
47         *(volatile uint8_t *) (bios + 0xAAA) = 0xF0;
48
49         myusec_delay(10);
50
51         printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
52
53
54         if (id1 == flash->manufacture_id && id2 == flash->model_id)
55                 return 1;
56
57         return 0;
58 }
59
60 int erase_m29f400bt(struct flashchip *flash)
61 {
62         volatile uint8_t *bios = flash->virt_addr;
63
64         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
65         *(volatile uint8_t *) (bios + 0x555) = 0x55;
66         *(volatile uint8_t *) (bios + 0xAAA) = 0x80;
67
68         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
69         *(volatile uint8_t *) (bios + 0x555) = 0x55;
70         *(volatile uint8_t *) (bios + 0xAAA) = 0x10;
71
72         myusec_delay(10);
73         toggle_ready_m29f400bt(bios);
74
75         return (0);
76 }
77
78 int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst)
79 {
80
81         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
82         *(volatile uint8_t *) (bios + 0x555) = 0x55;
83         *(volatile uint8_t *) (bios + 0xAAA) = 0x80;
84
85         *(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
86         *(volatile uint8_t *) (bios + 0x555) = 0x55;
87         //*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
88         *dst = 0x30;
89
90         myusec_delay(10);
91         toggle_ready_m29f400bt(bios);
92
93         return (0);
94 }
95
96 int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
97 {
98         int i;
99         int total_size = flash->total_size * 1024, page_size =
100             flash->page_size;
101         volatile uint8_t *bios = flash->virt_addr;
102
103         //erase_m29f400bt (flash);
104         printf("Programming Page:\n ");
105         /*********************************
106         *Pages for M29F400BT:
107         * 16    0x7c000         0x7ffff         TOP
108         *  8    0x7a000         0x7bfff
109         *  8    0x78000         0x79fff
110         * 32    0x70000         0x77fff
111         * 64    0x60000         0x6ffff
112         * 64    0x50000         0x5ffff
113         * 64    0x40000         0x4ffff
114         *---------------------------------
115         * 64    0x30000         0x3ffff
116         * 64    0x20000         0x2ffff
117         * 64    0x10000         0x1ffff
118         * 64    0x00000         0x0ffff         BOTTOM
119         *********************************/
120         printf("total_size/page_size = %d\n", total_size / page_size);
121         for (i = 0; i < (total_size / page_size) - 1; i++) {
122                 printf("%04d at address: 0x%08x\n", i, i * page_size);
123                 block_erase_m29f400bt(bios, bios + i * page_size);
124                 write_page_m29f400bt(bios, buf + i * page_size,
125                                      bios + i * page_size, page_size);
126                 printf
127                     ("\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");
128         }
129
130         printf("%04d at address: 0x%08x\n", 7, 0x70000);
131         block_erase_m29f400bt(bios, bios + 0x70000);
132         write_page_m29f400bt(bios, buf + 0x70000, bios + 0x70000,
133                              32 * 1024);
134
135         printf("%04d at address: 0x%08x\n", 8, 0x78000);
136         block_erase_m29f400bt(bios, bios + 0x78000);
137         write_page_m29f400bt(bios, buf + 0x78000, bios + 0x78000,
138                              8 * 1024);
139
140         printf("%04d at address: 0x%08x\n", 9, 0x7a000);
141         block_erase_m29f400bt(bios, bios + 0x7a000);
142         write_page_m29f400bt(bios, buf + 0x7a000, bios + 0x7a000,
143                              8 * 1024);
144
145         printf("%04d at address: 0x%08x\n", 10, 0x7c000);
146         block_erase_m29f400bt(bios, bios + 0x7c000);
147         write_page_m29f400bt(bios, buf + 0x7c000, bios + 0x7c000,
148                              16 * 1024);
149
150         printf("\n");
151         //protect_m29f400bt (bios);
152
153         return (0);
154 }
155
156 int write_linuxbios_m29f400bt(struct flashchip *flash, uint8_t *buf)
157 {
158         volatile uint8_t *bios = flash->virt_addr;
159
160         printf("Programming Page:\n ");
161         /*********************************
162         *Pages for M29F400BT:
163         * 16    0x7c000         0x7ffff         TOP
164         *  8    0x7a000         0x7bfff
165         *  8    0x78000         0x79fff
166         * 32    0x70000         0x77fff
167         * 64    0x60000         0x6ffff
168         * 64    0x50000         0x5ffff
169         * 64    0x40000         0x4ffff
170         *---------------------------------
171         * 64    0x30000         0x3ffff
172         * 64    0x20000         0x2ffff
173         * 64    0x10000         0x1ffff
174         * 64    0x00000         0x0ffff         BOTTOM
175         *********************************/
176         printf("%04d at address: 0x%08x\n", 7, 0x00000);
177         block_erase_m29f400bt(bios, bios + 0x00000);
178         write_page_m29f400bt(bios, buf + 0x00000, bios + 0x00000,
179                              64 * 1024);
180
181         printf("%04d at address: 0x%08x\n", 7, 0x10000);
182         block_erase_m29f400bt(bios, bios + 0x10000);
183         write_page_m29f400bt(bios, buf + 0x10000, bios + 0x10000,
184                              64 * 1024);
185
186         printf("%04d at address: 0x%08x\n", 7, 0x20000);
187         block_erase_m29f400bt(bios, bios + 0x20000);
188         write_page_m29f400bt(bios, buf + 0x20000, bios + 0x20000,
189                              64 * 1024);
190
191         printf("%04d at address: 0x%08x\n", 7, 0x30000);
192         block_erase_m29f400bt(bios, bios + 0x30000);
193         write_page_m29f400bt(bios, buf + 0x30000, bios + 0x30000,
194                              64 * 1024);
195
196         printf("\n");
197         //protect_m29f400bt (bios);
198
199         return (0);
200 }