FreeCalypso > hg > fc-magnetite
comparison src/cs/drivers/drv_app/ffs/board/intelsbdrv.c @ 0:945cf7f506b2
src/cs: chipsetsw import from tcs211-fcmodem
binary blobs and LCD demo files have been excluded,
all line endings are LF only
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Sun, 25 Sep 2016 22:50:11 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:945cf7f506b2 |
|---|---|
| 1 /****************************************************************************** | |
| 2 * Flash File System (ffs) | |
| 3 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com | |
| 4 * | |
| 5 * FFS AMD single bank low level flash driver RAM code | |
| 6 * | |
| 7 * $Id: intelsbdrv.c 1.13 Thu, 08 Jan 2004 15:05:23 +0100 tsj $ | |
| 8 * | |
| 9 ******************************************************************************/ | |
| 10 | |
| 11 #include "ffs.cfg" | |
| 12 | |
| 13 #include "ffs/ffs.h" | |
| 14 #include "ffs/board/drv.h" | |
| 15 #include "ffs/board/ffstrace.h" | |
| 16 | |
| 17 | |
| 18 #define INTEL_UNLOCK_SLOW 1 | |
| 19 | |
| 20 | |
| 21 #undef tlw | |
| 22 #define tlw(contents) | |
| 23 #undef ttw | |
| 24 #define ttw(contents) | |
| 25 | |
| 26 // Status bits for Intel flash memory devices | |
| 27 #define INTEL_STATE_MACHINE_DONE (1<<7) | |
| 28 #define FLASH_READ(addr) (*(volatile uint16 *) (addr)) | |
| 29 #define FLASH_WRITE(addr, data) (*(volatile uint16 *) (addr)) = data | |
| 30 | |
| 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 /****************************************************************************** | |
| 38 * INTEL Single Bank Driver Functions | |
| 39 ******************************************************************************/ | |
| 40 // Actually we should have disabled and enable the interrupts in this | |
| 41 // function, but when the interrupt functions are used Target don't run! | |
| 42 // Anyway, currently the interrupts are already disabled at this point thus | |
| 43 // it does not cause any problems. | |
| 44 int ffsdrv_ram_intel_sb_init(void) | |
| 45 { | |
| 46 uint32 cpsr, i; | |
| 47 volatile char *addr; | |
| 48 uint16 status; | |
| 49 | |
| 50 for (i = 0; i < dev.numblocks; i++) | |
| 51 { | |
| 52 addr = block2addr(i); | |
| 53 | |
| 54 *addr = 0x50; // Intel Clear Status Register | |
| 55 *addr = 0xFF; // Intel read array | |
| 56 | |
| 57 *addr = 0x60; // Intel Config Setup | |
| 58 *addr = 0xD0; // Intel Unlock Block | |
| 59 | |
| 60 // Wait for unlock to finish | |
| 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 } | |
| 81 | |
| 82 return 0; | |
| 83 } | |
| 84 | |
| 85 void ffsdrv_ram_intel_sb_write_halfword(volatile uint16 *addr, uint16 value) | |
| 86 { | |
| 87 uint32 cpsr; | |
| 88 | |
| 89 ttw(ttr(TTrDrv, "wh(%x,%x)" NL, addr, value)); | |
| 90 | |
| 91 if (~*addr & value) { | |
| 92 ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value)); | |
| 93 return; | |
| 94 } | |
| 95 | |
| 96 cpsr = intel_int_disable(); | |
| 97 tlw(led_on(LED_WRITE)); | |
| 98 | |
| 99 #if (INTEL_UNLOCK_SLOW == 1) | |
| 100 *addr = 0x60; // Intel Config Setup | |
| 101 *addr = 0xD0; // Intel Unlock Block | |
| 102 #endif | |
| 103 | |
| 104 *addr = 0x50; // Intel Clear Status Register | |
| 105 *addr = 0x40; // Intel program byte/word | |
| 106 *addr = value; | |
| 107 while ((*addr & 0x80) == 0) | |
| 108 ; | |
| 109 *addr = 0xFF; // Intel read array | |
| 110 tlw(led_off(LED_WRITE)); | |
| 111 intel_int_enable(cpsr); | |
| 112 } | |
| 113 | |
| 114 void ffsdrv_ram_intel_sb_erase(uint8 block) | |
| 115 { | |
| 116 volatile char *addr; | |
| 117 uint32 cpsr; | |
| 118 uint16 poll; | |
| 119 | |
| 120 ttw(ttr(TTrDrvEra, "e(%d)" NL, block)); | |
| 121 | |
| 122 addr = block2addr(block); | |
| 123 | |
| 124 cpsr = intel_int_disable(); | |
| 125 tlw(led_on(LED_ERASE)); | |
| 126 | |
| 127 #if (INTEL_UNLOCK_SLOW == 1) | |
| 128 *addr = 0x60; // Intel Config Setup | |
| 129 *addr = 0xD0; // Intel Unlock Block | |
| 130 #endif | |
| 131 | |
| 132 *addr = 0x50; // Intel Clear Status Register | |
| 133 *addr = 0x20; // Intel Erase Setup | |
| 134 *addr = 0xD0; // Intel Erase Confirm | |
| 135 *addr = 0x70; // Intel Read Status Register | |
| 136 | |
| 137 // Wait for erase to finish. | |
| 138 while ((*addr & 0x80) == 0) { | |
| 139 tlw(led_toggle(LED_ERASE)); | |
| 140 // Poll interrupts, taking interrupt mask into account. | |
| 141 if (INT_REQUESTED) | |
| 142 { | |
| 143 // 1. suspend erase | |
| 144 // 2. enable interrupts | |
| 145 // .. now the interrupt code executes | |
| 146 // 3. disable interrupts | |
| 147 // 4. resume erase | |
| 148 | |
| 149 tlw(led_on(LED_ERASE_SUSPEND)); | |
| 150 | |
| 151 *addr = 0xB0; // Intel Erase Suspend | |
| 152 *addr = 0x70; // Intel Read Status Register | |
| 153 while (((poll = *addr) & 0x80) == 0) | |
| 154 ; | |
| 155 | |
| 156 // If erase is complete, exit immediately | |
| 157 if ((poll & 0x40) == 0) | |
| 158 break; | |
| 159 | |
| 160 *addr = 0xFF; // Intel read array | |
| 161 | |
| 162 tlw(led_off(LED_ERASE_SUSPEND)); | |
| 163 intel_int_enable(cpsr); | |
| 164 | |
| 165 // Other interrupts and tasks run now... | |
| 166 | |
| 167 cpsr = intel_int_disable(); | |
| 168 tlw(led_on(LED_ERASE_SUSPEND)); | |
| 169 | |
| 170 *addr = 0xD0; // Intel erase resume | |
| 171 // The following "extra" Read Status command is required because Intel has | |
| 172 // changed the specification of the W30 flash! (See "1.8 Volt Intel® | |
| 173 // Wireless Flash Memory with 3 Volt I/O 28F6408W30, 28F640W30, 28F320W30 | |
| 174 // Specification Update") | |
| 175 *addr = 0x70; // Intel Read Status Register | |
| 176 | |
| 177 tlw(led_off(LED_ERASE_SUSPEND)); | |
| 178 } | |
| 179 } | |
| 180 *addr = 0xFF; // Intel read array | |
| 181 | |
| 182 tlw(led_on(LED_ERASE)); | |
| 183 tlw(led_off(LED_ERASE)); | |
| 184 intel_int_enable(cpsr); | |
| 185 } | |
| 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"); |
