add new dfboot loader - a complete revison of romboot code.
[openwrt/svn-archive/archive.git] / target / linux / at91-2.6 / image / dfboot / src / dataflash.c
1 /*----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support - ROUSSET -
3 *----------------------------------------------------------------------------
4 * The software is delivered "AS IS" without warranty or condition of any
5 * kind, either express, implied or statutory. This includes without
6 * limitation any warranty or condition with respect to merchantability or
7 * fitness for any particular purpose, or against the infringements of
8 * intellectual property rights of others.
9 *----------------------------------------------------------------------------
10 * File Name : dataflash.c
11 * Object : High level functions for the dataflash
12 * Creation : HIi 10/10/2003
13 *----------------------------------------------------------------------------
14 */
15 #include "config.h"
16 #include "stdio.h"
17 #include "dataflash.h"
18
19
20 AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
21 static AT91S_DataFlash DataFlashInst;
22
23 int cs[][CFG_MAX_DATAFLASH_BANKS] = {
24 {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */
25 {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
26 };
27
28 int AT91F_DataflashInit(void)
29 {
30 int i;
31 int dfcode;
32 int Nb_device = 0;
33
34 AT91F_SpiInit();
35
36 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
37 dataflash_info[i].id = 0;
38 dataflash_info[i].Device.pages_number = 0;
39 dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
40
41 switch (dfcode) {
42 case AT45DB161:
43 dataflash_info[i].Device.pages_number = 4096;
44 dataflash_info[i].Device.pages_size = 528;
45 dataflash_info[i].Device.page_offset = 10;
46 dataflash_info[i].Device.byte_mask = 0x300;
47 dataflash_info[i].Device.cs = cs[i][1];
48 dataflash_info[i].Desc.DataFlash_state = IDLE;
49 dataflash_info[i].logical_address = cs[i][0];
50 dataflash_info[i].id = dfcode;
51 Nb_device++;
52 break;
53
54 case AT45DB321:
55 dataflash_info[i].Device.pages_number = 8192;
56 dataflash_info[i].Device.pages_size = 528;
57 dataflash_info[i].Device.page_offset = 10;
58 dataflash_info[i].Device.byte_mask = 0x300;
59 dataflash_info[i].Device.cs = cs[i][1];
60 dataflash_info[i].Desc.DataFlash_state = IDLE;
61 dataflash_info[i].logical_address = cs[i][0];
62 dataflash_info[i].id = dfcode;
63 Nb_device++;
64 break;
65
66 case AT45DB642:
67 dataflash_info[i].Device.pages_number = 8192;
68 dataflash_info[i].Device.pages_size = 1056;
69 dataflash_info[i].Device.page_offset = 11;
70 dataflash_info[i].Device.byte_mask = 0x700;
71 dataflash_info[i].Device.cs = cs[i][1];
72 dataflash_info[i].Desc.DataFlash_state = IDLE;
73 dataflash_info[i].logical_address = cs[i][0];
74 dataflash_info[i].id = dfcode;
75 Nb_device++;
76 break;
77 case AT45DB128:
78 dataflash_info[i].Device.pages_number = 16384;
79 dataflash_info[i].Device.pages_size = 1056;
80 dataflash_info[i].Device.page_offset = 11;
81 dataflash_info[i].Device.byte_mask = 0x700;
82 dataflash_info[i].Device.cs = cs[i][1];
83 dataflash_info[i].Desc.DataFlash_state = IDLE;
84 dataflash_info[i].logical_address = cs[i][0];
85 dataflash_info[i].id = dfcode;
86 Nb_device++;
87 break;
88 default:
89 break;
90 }
91 }
92 return (Nb_device);
93 }
94
95
96 void AT91F_DataflashPrintInfo(void)
97 {
98 int i;
99 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
100 if (dataflash_info[i].id != 0) {
101 printf ("DF:AT45DB");
102 switch (dataflash_info[i].id) {
103 case AT45DB161:
104 printf ("161");
105 break;
106
107 case AT45DB321:
108 printf ("321");
109 break;
110
111 case AT45DB642:
112 printf ("642");
113 break;
114 case AT45DB128:
115 printf ("128");
116 break;
117 }
118
119 printf ("\n# PG: %6d\n"
120 "PG SZ: %6d\n"
121 "SZ=%8d bytes\n"
122 "ADDR: %08X\n",
123 (unsigned int) dataflash_info[i].Device.pages_number,
124 (unsigned int) dataflash_info[i].Device.pages_size,
125 (unsigned int) dataflash_info[i].Device.pages_number *
126 dataflash_info[i].Device.pages_size,
127 (unsigned int) dataflash_info[i].logical_address);
128 }
129 }
130 }
131
132
133 /*------------------------------------------------------------------------------*/
134 /* Function Name : AT91F_DataflashSelect */
135 /* Object : Select the correct device */
136 /*------------------------------------------------------------------------------*/
137 static AT91PS_DataFlash AT91F_DataflashSelect(AT91PS_DataFlash pFlash,
138 unsigned int *addr)
139 {
140 char addr_valid = 0;
141 int i;
142
143 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
144 if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
145 addr_valid = 1;
146 break;
147 }
148 if (!addr_valid) {
149 pFlash = (AT91PS_DataFlash) 0;
150 return pFlash;
151 }
152 pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
153 pFlash->pDevice = &(dataflash_info[i].Device);
154 *addr -= dataflash_info[i].logical_address;
155 return (pFlash);
156 }
157
158
159 /*------------------------------------------------------------------------------*/
160 /* Function Name : read_dataflash */
161 /* Object : dataflash memory read */
162 /*------------------------------------------------------------------------------*/
163 int read_dataflash(unsigned long addr, unsigned long size, char *result)
164 {
165 unsigned int AddrToRead = addr;
166 AT91PS_DataFlash pFlash = &DataFlashInst;
167
168 pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
169 if (pFlash == 0)
170 return -1;
171
172 return (AT91F_DataFlashRead(pFlash, AddrToRead, size, result));
173 }
174
175
176 /*-----------------------------------------------------------------------------*/
177 /* Function Name : write_dataflash */
178 /* Object : write a block in dataflash */
179 /*-----------------------------------------------------------------------------*/
180 int write_dataflash(unsigned long addr_dest, unsigned int addr_src,
181 unsigned int size)
182 {
183 unsigned int AddrToWrite = addr_dest;
184 AT91PS_DataFlash pFlash = &DataFlashInst;
185
186 pFlash = AT91F_DataflashSelect(pFlash, &AddrToWrite);
187 if (AddrToWrite == -1)
188 return -1;
189
190 return AT91F_DataFlashWrite(pFlash, (unsigned char *) addr_src, AddrToWrite, size);
191 }
192
193 /*-----------------------------------------------------------------------------*/
194 /* Function Name : erase_dataflash */
195 /* Object : Erase entire dataflash */
196 /*-----------------------------------------------------------------------------*/
197 int erase_dataflash(unsigned long addr_dest)
198 {
199 unsigned int AddrToWrite = addr_dest;
200 AT91PS_DataFlash pFlash = &DataFlashInst;
201
202 pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
203 if (AddrToWrite == -1)
204 return -1;
205
206 return AT91F_DataFlashErase(pFlash);
207 }
208