big cosmetic offensive on flashrom. (trivial)
[coreboot.git] / util / flashrom / am29f040b.c
1 /*
2  * am29f040.c: driver for programming AMD am29f040b models
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  * Reference:
22  *      AMD Am29F040B data sheet
23  */
24
25 #include <stdio.h>
26 #include <stdint.h>
27 #include "flash.h"
28 #include "jedec.h"
29 #include "debug.h"
30
31 static __inline__ int erase_sector_29f040b(volatile uint8_t *bios,
32                                            unsigned long address)
33 {
34         *(bios + 0x555) = 0xAA;
35         *(bios + 0x2AA) = 0x55;
36         *(bios + 0x555) = 0x80;
37         *(bios + 0x555) = 0xAA;
38         *(bios + 0x2AA) = 0x55;
39         *(bios + address) = 0x30;
40
41         sleep(2);
42
43         /* wait for Toggle bit ready         */
44         toggle_ready_jedec(bios + address);
45
46         return (0);
47 }
48
49 static __inline__ int write_sector_29f040b(volatile uint8_t *bios,
50                                            uint8_t *src,
51                                            volatile uint8_t *dst,
52                                            unsigned int page_size)
53 {
54         int i;
55
56         for (i = 0; i < page_size; i++) {
57                 if ((i & 0xfff) == 0xfff)
58                         printf("0x%08lx", (unsigned long)dst -
59                                (unsigned long)bios);
60
61                 *(bios + 0x555) = 0xAA;
62                 *(bios + 0x2AA) = 0x55;
63                 *(bios + 0x555) = 0xA0;
64                 *dst++ = *src++;
65
66                 /* wait for Toggle bit ready */
67                 toggle_ready_jedec(bios);
68
69                 if ((i & 0xfff) == 0xfff)
70                         printf("\b\b\b\b\b\b\b\b\b\b");
71         }
72
73         return (0);
74 }
75
76 int probe_29f040b(struct flashchip *flash)
77 {
78         volatile uint8_t *bios = flash->virtual_memory;
79         uint8_t id1, id2;
80
81         *(bios + 0x555) = 0xAA;
82         *(bios + 0x2AA) = 0x55;
83         *(bios + 0x555) = 0x90;
84
85         id1 = *bios;
86         id2 = *(bios + 0x01);
87
88         *bios = 0xF0;
89
90         myusec_delay(10);
91
92         printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
93         if (id1 == flash->manufacture_id && id2 == flash->model_id)
94                 return 1;
95
96         return 0;
97 }
98
99 int erase_29f040b(struct flashchip *flash)
100 {
101         volatile uint8_t *bios = flash->virtual_memory;
102
103         *(bios + 0x555) = 0xAA;
104         *(bios + 0x2AA) = 0x55;
105         *(bios + 0x555) = 0x80;
106         *(bios + 0x555) = 0xAA;
107         *(bios + 0x2AA) = 0x55;
108         *(bios + 0x555) = 0x10;
109
110         myusec_delay(10);
111         toggle_ready_jedec(bios);
112
113         return (0);
114 }
115
116 int write_29f040b(struct flashchip *flash, uint8_t *buf)
117 {
118         int i;
119         int total_size = flash->total_size * 1024;
120         int page_size = flash->page_size;
121         volatile uint8_t *bios = flash->virtual_memory;
122
123         printf("Programming page ");
124         for (i = 0; i < total_size / page_size; i++) {
125                 /* erase the page before programming */
126                 erase_sector_29f040b(bios, i * page_size);
127
128                 /* write to the sector */
129                 printf("%04d at address: ", i);
130                 write_sector_29f040b(bios, buf + i * page_size,
131                                      bios + i * page_size, page_size);
132                 printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
133         }
134         printf("\n");
135
136         return (0);
137 }