comparison gsm-fw/services/ffs/intelsbdrv.c @ 939:62ca61292b77

gsm-fw: Intel single bank flash driver (Compal) compiles and links
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Sat, 31 Oct 2015 23:21:40 +0000
parents 1db4da08b9b4
children 51f580665110
comparison
equal deleted inserted replaced
938:1db4da08b9b4 939:62ca61292b77
6 * 6 *
7 * $Id: intelsbdrv.c 1.13 Thu, 08 Jan 2004 15:05:23 +0100 tsj $ 7 * $Id: intelsbdrv.c 1.13 Thu, 08 Jan 2004 15:05:23 +0100 tsj $
8 * 8 *
9 ******************************************************************************/ 9 ******************************************************************************/
10 10
11 #include "ffs.cfg" 11 #include "../../include/config.h"
12 12 #include "ffs.h"
13 #include "ffs/ffs.h" 13 #include "drv.h"
14 #include "ffs/board/drv.h" 14 #include "ffstrace.h"
15 #include "ffs/board/ffstrace.h" 15 #include "intctl.h"
16
17
18 #define INTEL_UNLOCK_SLOW 1
19 16
20 17
21 #undef tlw 18 #undef tlw
22 #define tlw(contents) 19 #define tlw(contents)
23 #undef ttw 20 #undef ttw
26 // Status bits for Intel flash memory devices 23 // Status bits for Intel flash memory devices
27 #define INTEL_STATE_MACHINE_DONE (1<<7) 24 #define INTEL_STATE_MACHINE_DONE (1<<7)
28 #define FLASH_READ(addr) (*(volatile uint16 *) (addr)) 25 #define FLASH_READ(addr) (*(volatile uint16 *) (addr))
29 #define FLASH_WRITE(addr, data) (*(volatile uint16 *) (addr)) = data 26 #define FLASH_WRITE(addr, data) (*(volatile uint16 *) (addr)) = data
30 27
31 asm(" .label _ffsdrv_ram_intel_begin");
32 asm(" .def _ffsdrv_ram_intel_begin");
33
34 uint32 intel_int_disable(void);
35 void intel_int_enable(uint32 tmp);
36
37 /****************************************************************************** 28 /******************************************************************************
38 * INTEL Single Bank Driver Functions 29 * INTEL Single Bank Driver Functions
39 ******************************************************************************/ 30 ******************************************************************************/
40 // Actually we should have disabled and enable the interrupts in this 31 // Actually we should have disabled and enable the interrupts in this
41 // function, but when the interrupt functions are used Target don't run! 32 // function, but when the interrupt functions are used Target don't run!
42 // Anyway, currently the interrupts are already disabled at this point thus 33 // Anyway, currently the interrupts are already disabled at this point thus
43 // it does not cause any problems. 34 // it does not cause any problems.
44 int ffsdrv_ram_intel_sb_init(void) 35 int ffsdrv_ram_intel_sb_init(void)
45 { 36 {
46 uint32 cpsr, i; 37 uint32 i;
47 volatile char *addr; 38 volatile uint16 *addr;
48 uint16 status;
49 39
50 for (i = 0; i < dev.numblocks; i++) 40 for (i = 0; i < dev.numblocks; i++)
51 { 41 {
52 addr = block2addr(i); 42 addr = (volatile uint16 *) block2addr(i);
53
54 *addr = 0x50; // Intel Clear Status Register
55 *addr = 0xFF; // Intel read array
56 43
57 *addr = 0x60; // Intel Config Setup 44 *addr = 0x60; // Intel Config Setup
58 *addr = 0xD0; // Intel Unlock Block 45 *addr = 0xD0; // Intel Unlock Block
59 46
60 // Wait for unlock to finish 47 *addr = 0xFF; // Intel Read Array
61 do {
62 status = FLASH_READ(addr);
63 } while (!(status & INTEL_STATE_MACHINE_DONE));
64
65 *addr = 0x70; // Intel Read Status Register
66 status = FLASH_READ(addr);
67
68 // Is there an erase suspended?
69 if ((status & 0x40) != 0) {
70 *addr = 0xD0; // Intel erase resume
71
72 *addr = 0x70; // Intel Read Status Register
73 // wait for erase to finish
74 do {
75 status = FLASH_READ(addr);
76 } while (!(status & INTEL_STATE_MACHINE_DONE));
77 }
78
79 *addr = 0xFF; // Intel Read Array
80 } 48 }
81 49
82 return 0; 50 return 0;
83 } 51 }
84 52
91 if (~*addr & value) { 59 if (~*addr & value) {
92 ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value)); 60 ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value));
93 return; 61 return;
94 } 62 }
95 63
96 cpsr = intel_int_disable(); 64 cpsr = int_disable();
97 tlw(led_on(LED_WRITE)); 65 tlw(led_on(LED_WRITE));
98 66
99 #if (INTEL_UNLOCK_SLOW == 1) 67 #if (INTEL_UNLOCK_SLOW == 1)
100 *addr = 0x60; // Intel Config Setup 68 *addr = 0x60; // Intel Config Setup
101 *addr = 0xD0; // Intel Unlock Block 69 *addr = 0xD0; // Intel Unlock Block
106 *addr = value; 74 *addr = value;
107 while ((*addr & 0x80) == 0) 75 while ((*addr & 0x80) == 0)
108 ; 76 ;
109 *addr = 0xFF; // Intel read array 77 *addr = 0xFF; // Intel read array
110 tlw(led_off(LED_WRITE)); 78 tlw(led_off(LED_WRITE));
111 intel_int_enable(cpsr); 79 int_enable(cpsr);
112 } 80 }
113 81
114 void ffsdrv_ram_intel_sb_erase(uint8 block) 82 void ffsdrv_ram_intel_sb_erase(uint8 block)
115 { 83 {
116 volatile char *addr; 84 volatile uint16 *addr;
117 uint32 cpsr; 85 uint32 cpsr;
118 uint16 poll; 86 uint16 poll;
119 87
120 ttw(ttr(TTrDrvEra, "e(%d)" NL, block)); 88 ttw(ttr(TTrDrvEra, "e(%d)" NL, block));
121 89
122 addr = block2addr(block); 90 addr = (volatile uint16 *) block2addr(block);
123 91
124 cpsr = intel_int_disable(); 92 cpsr = int_disable();
125 tlw(led_on(LED_ERASE)); 93 tlw(led_on(LED_ERASE));
126 94
127 #if (INTEL_UNLOCK_SLOW == 1) 95 #if (INTEL_UNLOCK_SLOW == 1)
128 *addr = 0x60; // Intel Config Setup 96 *addr = 0x60; // Intel Config Setup
129 *addr = 0xD0; // Intel Unlock Block 97 *addr = 0xD0; // Intel Unlock Block
130 #endif 98 #endif
131 99
132 *addr = 0x50; // Intel Clear Status Register 100 *addr = 0x50; // Intel Clear Status Register
133 *addr = 0x20; // Intel Erase Setup 101 *addr = 0x20; // Intel Erase Setup
134 *addr = 0xD0; // Intel Erase Confirm 102 *addr = 0xD0; // Intel Erase Confirm
135 *addr = 0x70; // Intel Read Status Register 103 *addr = 0x70; // Intel Read Status Register
136 104
137 // Wait for erase to finish. 105 // Wait for erase to finish.
138 while ((*addr & 0x80) == 0) { 106 while ((*addr & 0x80) == 0) {
139 tlw(led_toggle(LED_ERASE)); 107 tlw(led_toggle(LED_ERASE));
140 // Poll interrupts, taking interrupt mask into account. 108 // Poll interrupts, taking interrupt mask into account.
158 break; 126 break;
159 127
160 *addr = 0xFF; // Intel read array 128 *addr = 0xFF; // Intel read array
161 129
162 tlw(led_off(LED_ERASE_SUSPEND)); 130 tlw(led_off(LED_ERASE_SUSPEND));
163 intel_int_enable(cpsr); 131 int_enable(cpsr);
164 132
165 // Other interrupts and tasks run now... 133 // Other interrupts and tasks run now...
166 134
167 cpsr = intel_int_disable(); 135 cpsr = int_disable();
168 tlw(led_on(LED_ERASE_SUSPEND)); 136 tlw(led_on(LED_ERASE_SUSPEND));
169 137
170 *addr = 0xD0; // Intel erase resume 138 *addr = 0xD0; // Intel erase resume
171 // The following "extra" Read Status command is required because Intel has 139 // The following "extra" Read Status command is required because Intel has
172 // changed the specification of the W30 flash! (See "1.8 Volt Intel® 140 // changed the specification of the W30 flash! (See "1.8 Volt Intel®
173 // Wireless Flash Memory with 3 Volt I/O 28F6408W30, 28F640W30, 28F320W30 141 // Wireless Flash Memory with 3 Volt I/O 28F6408W30, 28F640W30, 28F320W30
174 // Specification Update") 142 // Specification Update")
175 *addr = 0x70; // Intel Read Status Register 143 *addr = 0x70; // Intel Read Status Register
176 144
177 tlw(led_off(LED_ERASE_SUSPEND)); 145 tlw(led_off(LED_ERASE_SUSPEND));
178 } 146 }
179 } 147 }
180 *addr = 0xFF; // Intel read array 148 *addr = 0xFF; // Intel read array
181 149
182 tlw(led_on(LED_ERASE)); 150 tlw(led_on(LED_ERASE));
183 tlw(led_off(LED_ERASE)); 151 tlw(led_off(LED_ERASE));
184 intel_int_enable(cpsr); 152 int_enable(cpsr);
185 } 153 }
186
187 // TODO: remove below function, not in use anymore.
188 void ffsdrv_ram_intel_erase(uint8 block)
189 {
190 uint32 cpsr;
191 uint16 status;
192
193 ttw(ttr(TTrDrvErase, "e(%d)" NL, block));
194 tlw(led_on(LED_ERASE));
195
196 dev.addr = (uint16 *) block2addr(block);
197
198 cpsr = intel_int_disable();
199 dev.state = DEV_ERASE;
200
201 *dev.addr = 0x60; // Intel Config setup
202 *dev.addr = 0xD0; // Intel Unlock block
203
204 *dev.addr = 0x50; // Intel clear status register (not really necessary)
205 *dev.addr = 0x20; // Intel erase setup
206 *dev.addr = 0xD0; // Intel erase confirm
207
208 intel_int_enable(cpsr);
209
210 while ((*dev.addr & 0x80) == 0)
211 ;
212
213 *dev.addr = 0xFF; // Intel read array
214 dev.state = DEV_READ;
215 tlw(led_off(LED_WRITE));
216 }
217
218
219 /******************************************************************************
220 * Interrupt Enable/Disable
221 ******************************************************************************/
222
223 uint32 intel_int_disable(void)
224 {
225 asm(" .state16");
226 asm(" mov A1, #0xC0");
227 asm(" ldr A2, tct_intel_disable");
228 asm(" bx A2 ");
229
230 asm("tct_intel_disable .field _TCT_Control_Interrupts+0,32");
231 asm(" .global _TCT_Control_Interrupts");
232 }
233
234 void intel_int_enable(uint32 cpsr)
235 {
236 asm(" .state16");
237 asm(" ldr A2, tct_intel_enable");
238 asm(" bx A2 ");
239
240 asm("tct_intel_enable .field _TCT_Control_Interrupts+0,32");
241 asm(" .global _TCT_Control_Interrupts");
242 }
243
244 // Even though we have this end label, we cannot determine the number of
245 // constant/PC-relative data following the code!
246 asm(" .state32");
247 asm(" .label _ffsdrv_ram_intel_end");
248 asm(" .def _ffsdrv_ram_intel_end");