[2a444594] | 1 | /* |
---|
| 2 | * Trivial driver for 16-bit intel flash present on the |
---|
| 3 | * MVME5500/MVME6100 boards. |
---|
| 4 | * |
---|
| 5 | * For recognized devices, look for 'intelDevs'. |
---|
| 6 | * |
---|
| 7 | * This driver currently only supports stride=4 and 16-bit |
---|
| 8 | * mode (width=2). |
---|
| 9 | */ |
---|
| 10 | |
---|
[ac7af4a] | 11 | /* |
---|
[2a444594] | 12 | * Authorship |
---|
| 13 | * ---------- |
---|
| 14 | * This software was created by |
---|
| 15 | * Till Straumann <strauman@slac.stanford.edu>, 2005-2007, |
---|
| 16 | * Stanford Linear Accelerator Center, Stanford University. |
---|
[ac7af4a] | 17 | * |
---|
[2a444594] | 18 | * Acknowledgement of sponsorship |
---|
| 19 | * ------------------------------ |
---|
| 20 | * The software was produced by |
---|
| 21 | * the Stanford Linear Accelerator Center, Stanford University, |
---|
| 22 | * under Contract DE-AC03-76SFO0515 with the Department of Energy. |
---|
[ac7af4a] | 23 | * |
---|
[2a444594] | 24 | * Government disclaimer of liability |
---|
| 25 | * ---------------------------------- |
---|
| 26 | * Neither the United States nor the United States Department of Energy, |
---|
| 27 | * nor any of their employees, makes any warranty, express or implied, or |
---|
| 28 | * assumes any legal liability or responsibility for the accuracy, |
---|
| 29 | * completeness, or usefulness of any data, apparatus, product, or process |
---|
| 30 | * disclosed, or represents that its use would not infringe privately owned |
---|
| 31 | * rights. |
---|
[ac7af4a] | 32 | * |
---|
[2a444594] | 33 | * Stanford disclaimer of liability |
---|
| 34 | * -------------------------------- |
---|
| 35 | * Stanford University makes no representations or warranties, express or |
---|
| 36 | * implied, nor assumes any liability for the use of this software. |
---|
[ac7af4a] | 37 | * |
---|
[2a444594] | 38 | * Stanford disclaimer of copyright |
---|
| 39 | * -------------------------------- |
---|
| 40 | * Stanford University, owner of the copyright, hereby disclaims its |
---|
| 41 | * copyright and all other rights in this software. Hence, anyone may |
---|
[ac7af4a] | 42 | * freely use it for any purpose without restriction. |
---|
| 43 | * |
---|
[2a444594] | 44 | * Maintenance of notices |
---|
| 45 | * ---------------------- |
---|
| 46 | * In the interest of clarity regarding the origin and status of this |
---|
| 47 | * SLAC software, this and all the preceding Stanford University notices |
---|
| 48 | * are to remain affixed to any copy or derivative of this software made |
---|
| 49 | * or distributed by the recipient and are to be affixed to any copy of |
---|
| 50 | * software made or distributed by the recipient that contains a copy or |
---|
| 51 | * derivative of this software. |
---|
[ac7af4a] | 52 | * |
---|
[2a444594] | 53 | * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 |
---|
[ac7af4a] | 54 | */ |
---|
[2a444594] | 55 | #ifdef TESTING |
---|
| 56 | |
---|
[5ece798] | 57 | #define TIMEOUT_US 100000 |
---|
| 58 | #define rtems_task_wake_after(t) sleep(t) |
---|
| 59 | #define CLOCKRATE_GET(p) (*(p)=1) |
---|
[2a444594] | 60 | |
---|
| 61 | #else |
---|
| 62 | |
---|
| 63 | #include <rtems.h> |
---|
[5ece798] | 64 | #define TIMEOUT_US 1000 |
---|
| 65 | #define CLOCKRATE_GET(p) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, p ) |
---|
[2a444594] | 66 | |
---|
| 67 | #endif |
---|
| 68 | |
---|
[5ece798] | 69 | #define ERASE_TIMEOUT_S 2 |
---|
| 70 | |
---|
[2a444594] | 71 | #include <stdio.h> |
---|
| 72 | #include <inttypes.h> |
---|
| 73 | #include <stdlib.h> |
---|
| 74 | |
---|
| 75 | #include <bsp/flashPgmPvt.h> |
---|
| 76 | |
---|
| 77 | #define DEBUG 0 |
---|
| 78 | #undef DEBUG |
---|
| 79 | |
---|
| 80 | #ifdef DEBUG |
---|
| 81 | #define STATIC |
---|
| 82 | #else |
---|
| 83 | #define STATIC static |
---|
| 84 | #endif |
---|
| 85 | |
---|
| 86 | #define NumberOf(arr) (sizeof(arr)/sizeof(arr[0])) |
---|
| 87 | |
---|
| 88 | /* This driver assumes two 16-bit devices in parallel */ |
---|
| 89 | |
---|
| 90 | /********* Register Definitions ****************/ |
---|
| 91 | |
---|
| 92 | /* command codes */ |
---|
| 93 | #define F_CMD_RD_ARR 0xffffffff /* back to 'normal' read mode */ |
---|
| 94 | #define F_CMD_RD_ID 0x90909090 /* read from ID space */ |
---|
| 95 | #define F_CMD_RD_STA 0x70707070 /* read status register */ |
---|
| 96 | #define F_CMD_WR_STA 0x50505050 /* clear status register */ |
---|
| 97 | #define F_CMD_WR_BUF 0xe8e8e8e8 /* write to buffer */ |
---|
| 98 | #define F_CMD_WR_WRD 0x40404040 /* write word */ |
---|
| 99 | #define F_CMD_WR_ERA 0x20202020 /* block erase */ |
---|
| 100 | #define F_CMD_WR_LCK 0x60606060 /* lock bit (1st cycle) */ |
---|
| 101 | #define F_CMD_WR_CMD 0xd0d0d0d0 /* commit erase */ |
---|
| 102 | #define F_CMD_WR_LCK_SET 0x01010101 /* lock block commit */ |
---|
| 103 | |
---|
| 104 | /* Status codes (F_CMD_RD_STA result) */ |
---|
| 105 | #define STA_RDY (1<<7) /* ready */ |
---|
| 106 | #define STA_ES (1<<6) /* erase suspend */ |
---|
| 107 | #define STA_EE (1<<5) /* erase error */ |
---|
| 108 | #define STA_PE (1<<4) /* program error */ |
---|
| 109 | #define STA_VE (1<<3) /* VPEN < min */ |
---|
| 110 | #define STA_PS (1<<2) /* program susp. */ |
---|
| 111 | #define STA_LE (1<<1) /* block locked */ |
---|
| 112 | #define STA_EFP (1<<0) /* buf. EFP stat.*/ |
---|
| 113 | |
---|
| 114 | /* Any error */ |
---|
| 115 | #define STA_ERROR (STA_EE|STA_PE|STA_VE|STA_LE) |
---|
| 116 | |
---|
| 117 | /* TODO: Code using RDYRDY assumes flash is 16-bit wide :-( */ |
---|
| 118 | #define STA_RDYRDY 0x00800080 /* ready status on both devices */ |
---|
| 119 | |
---|
| 120 | /********* Forward Declarations ****************/ |
---|
| 121 | |
---|
| 122 | STATIC int |
---|
| 123 | flash_get_id_intel(struct bankdesc *, uint32_t, uint32_t *, uint32_t *); |
---|
| 124 | |
---|
| 125 | STATIC void |
---|
| 126 | flash_unlock_block_intel(struct bankdesc *, uint32_t); |
---|
| 127 | |
---|
| 128 | STATIC void |
---|
| 129 | flash_lock_block_intel(struct bankdesc *, uint32_t); |
---|
| 130 | |
---|
| 131 | STATIC int |
---|
| 132 | flash_erase_block_intel(struct bankdesc *, uint32_t); |
---|
| 133 | |
---|
| 134 | STATIC uint32_t |
---|
| 135 | flash_check_ready_intel(struct bankdesc *, uint32_t); |
---|
| 136 | |
---|
| 137 | STATIC void |
---|
| 138 | flash_print_stat_intel(struct bankdesc *, uint32_t, int); |
---|
| 139 | |
---|
| 140 | STATIC void |
---|
| 141 | flash_array_mode_intel(struct bankdesc *, uint32_t); |
---|
| 142 | |
---|
| 143 | STATIC uint32_t |
---|
| 144 | flash_write_line_intel(struct bankdesc *, uint32_t, char *, uint32_t); |
---|
| 145 | |
---|
| 146 | /********* Global Variables ********************/ |
---|
| 147 | |
---|
| 148 | static struct flash_bank_ops intelOps = { |
---|
| 149 | get_id : flash_get_id_intel, |
---|
| 150 | unlock_block: flash_unlock_block_intel, |
---|
| 151 | lock_block : flash_lock_block_intel, |
---|
| 152 | erase_block : flash_erase_block_intel, |
---|
| 153 | check_ready : flash_check_ready_intel, |
---|
| 154 | print_stat : flash_print_stat_intel, |
---|
| 155 | array_mode : flash_array_mode_intel, |
---|
| 156 | write_line : flash_write_line_intel, |
---|
| 157 | }; |
---|
| 158 | |
---|
| 159 | static struct devdesc intelDevs[] = { |
---|
| 160 | { 0x8801, "K3 64Mb", 8*1024*1024, 0x40, 0x20000 }, |
---|
| 161 | { 0x8802, "K3 128Mb", 16*1024*1024, 0x40, 0x20000 }, |
---|
| 162 | { 0x8803, "K3 256Mb", 32*1024*1024, 0x40, 0x20000 }, |
---|
| 163 | { 0x8805, "K18 64Mb", 8*1024*1024, 0x40, 0x20000 }, |
---|
| 164 | { 0x8806, "K18 128Mb", 16*1024*1024, 0x40, 0x20000 }, |
---|
| 165 | { 0x8807, "K18 256Mb", 32*1024*1024, 0x40, 0x20000 }, |
---|
| 166 | { 0x0016, "J3 32Mb", 4*1024*1024, 0x20, 0x20000 }, |
---|
| 167 | { 0x0017, "J3 64Mb", 8*1024*1024, 0x20, 0x20000 }, |
---|
| 168 | { 0x0018, "J3 128Mb", 16*1024*1024, 0x20, 0x20000 }, |
---|
| 169 | { 0x001d, "J3 256Mb", 32*1024*1024, 0x20, 0x20000 }, |
---|
| 170 | { 0, 0, 0, 0} |
---|
| 171 | }; |
---|
| 172 | |
---|
| 173 | struct vendesc BSP_flash_vendor_intel[] = |
---|
| 174 | { |
---|
| 175 | { 0x89, "Intel", intelDevs, &intelOps }, |
---|
| 176 | { 0, 0} |
---|
| 177 | }; |
---|
| 178 | |
---|
| 179 | /********* Helper Subroutines ******************/ |
---|
| 180 | |
---|
[ac7af4a] | 181 | /* Basic low-level access routine for writing a command to the |
---|
[2a444594] | 182 | * internal state machine. |
---|
| 183 | * |
---|
| 184 | * Flash is slow, so who cares if these access routines |
---|
| 185 | * are not extremely efficient... |
---|
| 186 | */ |
---|
| 187 | STATIC uint32_t |
---|
| 188 | BSP_flashReadRaw(uint32_t cmd, uint32_t addr) |
---|
| 189 | { |
---|
| 190 | #if DEBUG > 4 |
---|
| 191 | printf("Writing CMD *0x%08"PRIx32" = 0x%08"PRIx32"\n", addr, cmd); |
---|
| 192 | #endif |
---|
| 193 | #ifdef TESTING |
---|
| 194 | return STA_RDYRDY; |
---|
| 195 | #else |
---|
| 196 | if ( cmd & 0xffff0000 ) { |
---|
| 197 | /* 32-bit access */ |
---|
| 198 | addr &= ~(sizeof(uint32_t)-1); |
---|
| 199 | *(A32)addr = cmd; |
---|
| 200 | return *(A32)addr; |
---|
| 201 | } else if ( cmd & 0xffffff00 ) { |
---|
| 202 | /* 16-bit access */ |
---|
| 203 | addr &= ~(sizeof(uint16_t)-1); |
---|
| 204 | *(A16)addr = cmd; |
---|
| 205 | return *(A16)addr; |
---|
| 206 | } else { |
---|
| 207 | *(A8)addr = cmd; |
---|
| 208 | return *(A8)addr; |
---|
| 209 | } |
---|
| 210 | #endif |
---|
| 211 | } |
---|
| 212 | |
---|
| 213 | STATIC void |
---|
| 214 | BSP_flashWriteRaw(uint32_t val, uint32_t addr) |
---|
| 215 | { |
---|
| 216 | #ifdef TESTING |
---|
| 217 | printf("Writing CNT *0x%08"PRIx32" = 0x%08"PRIx32"\n", addr, val); |
---|
| 218 | #else |
---|
| 219 | /* TODO implicitly assumes FLASH_WIDTH = 2, FLASH_NDEVS = 2 */ |
---|
| 220 | /* 32-bit access */ |
---|
| 221 | addr &= ~(sizeof(uint32_t)-1); |
---|
| 222 | *(A32)addr = val; |
---|
| 223 | #endif |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | STATIC uint32_t |
---|
| 227 | flash_pend(struct bankdesc *b, uint32_t a, uint32_t timeout_us) |
---|
| 228 | { |
---|
| 229 | uint32_t then, now, sta; |
---|
| 230 | |
---|
| 231 | then = BSP_flashBspOps.read_us_timer(); |
---|
| 232 | |
---|
| 233 | do { |
---|
| 234 | sta = BSP_flashReadRaw(F_CMD_RD_STA, a); |
---|
| 235 | now = BSP_flashBspOps.read_us_timer(); |
---|
| 236 | if ( now-then > timeout_us ) { |
---|
| 237 | /* timeout */ |
---|
| 238 | sta = -1; |
---|
| 239 | break; |
---|
| 240 | } |
---|
| 241 | } while ( STA_RDYRDY != (STA_RDYRDY & sta) ); |
---|
| 242 | |
---|
| 243 | /* switch back to normal mode */ |
---|
| 244 | flash_array_mode_intel(b, a); |
---|
| 245 | |
---|
| 246 | return STA_RDYRDY == sta ? 0 : sta; |
---|
| 247 | } |
---|
| 248 | |
---|
| 249 | |
---|
| 250 | /********* Access Methods **********************/ |
---|
| 251 | |
---|
| 252 | STATIC void |
---|
| 253 | flash_array_mode_intel(struct bankdesc *b, uint32_t a) |
---|
| 254 | { |
---|
| 255 | BSP_flashReadRaw(F_CMD_RD_ARR, a); |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | /* Dump status bits (F_CMD_RD_STA results); 'verbose' prints non-error bits, too */ |
---|
| 259 | STATIC void |
---|
| 260 | flash_print_stat_intel(struct bankdesc *b, uint32_t sta, int verbose) |
---|
| 261 | { |
---|
| 262 | int ch; |
---|
| 263 | if ( sta & STA_ERROR ) { |
---|
| 264 | ch = ':'; |
---|
| 265 | fprintf(stderr,"Errors found"); |
---|
| 266 | if ( STA_EE & sta ) { |
---|
| 267 | fprintf(stderr,"%c ERASE",ch); |
---|
| 268 | ch = ','; |
---|
| 269 | } |
---|
| 270 | if ( STA_PE & sta ) { |
---|
| 271 | fprintf(stderr,"%c PROGRAM",ch); |
---|
| 272 | ch = ','; |
---|
| 273 | } |
---|
| 274 | if ( STA_VE & sta ) { |
---|
| 275 | fprintf(stderr,"%c VPEN TOO LOW",ch); |
---|
| 276 | ch = ','; |
---|
| 277 | } |
---|
| 278 | if ( STA_LE & sta ) { |
---|
| 279 | fprintf(stderr,"%c BLOCK LOCKED",ch); |
---|
| 280 | ch = ','; |
---|
| 281 | } |
---|
| 282 | fprintf(stderr,"\n"); |
---|
| 283 | } |
---|
| 284 | if ( verbose ) { |
---|
| 285 | fprintf(stderr,"%sREADY\n",STA_RDY & sta ? "" : "NOT "); |
---|
| 286 | } |
---|
| 287 | } |
---|
| 288 | |
---|
| 289 | |
---|
| 290 | /* Query the status of the device and assert it's readiness |
---|
| 291 | * leave off in array-reading mode. |
---|
| 292 | * |
---|
| 293 | * RETURNS: 0 on success, error status (result of status query) on error. |
---|
| 294 | * |
---|
| 295 | * NOTES: - error message is printed to stderr. |
---|
| 296 | * - device switched back to array mode on exit. |
---|
| 297 | * - 'addr' must be 32-bit aligned. |
---|
| 298 | */ |
---|
| 299 | STATIC uint32_t |
---|
| 300 | flash_check_ready_intel(struct bankdesc *b, uint32_t addr) |
---|
| 301 | { |
---|
| 302 | uint32_t sta; |
---|
| 303 | |
---|
| 304 | (void)BSP_flashReadRaw(F_CMD_WR_STA, addr); |
---|
| 305 | if ( STA_RDYRDY != (STA_RDYRDY & (sta=BSP_flashReadRaw(F_CMD_RD_STA, addr))) ) { |
---|
| 306 | fprintf(stderr,"Flash not ready (@0x%08"PRIx32")\n", addr); |
---|
| 307 | flash_print_stat_intel(b, sta, 0); |
---|
| 308 | } else { |
---|
| 309 | sta = 0; |
---|
| 310 | } |
---|
| 311 | /* switch back to normal mode */ |
---|
| 312 | flash_array_mode_intel(b, addr); |
---|
| 313 | return sta; |
---|
| 314 | } |
---|
| 315 | |
---|
| 316 | /* Erase single block holding 'addr'ess |
---|
| 317 | * |
---|
| 318 | * RETURNS: zero on error, device status on failure. |
---|
| 319 | * |
---|
| 320 | * NOTES: - device switched back to array mode on exit. |
---|
| 321 | * - 'addr' must be 32-bit aligned. |
---|
| 322 | */ |
---|
| 323 | STATIC int |
---|
| 324 | flash_erase_block_intel(struct bankdesc *b, uint32_t addr) |
---|
| 325 | { |
---|
[5ece798] | 326 | uint32_t sta; |
---|
| 327 | int i; |
---|
| 328 | rtems_interval p; |
---|
| 329 | |
---|
[2a444594] | 330 | if ( (sta = flash_check_ready_intel(b, addr)) ) |
---|
| 331 | return sta; |
---|
| 332 | |
---|
| 333 | (void)BSP_flashReadRaw(F_CMD_WR_ERA, addr); |
---|
| 334 | (void)BSP_flashReadRaw(F_CMD_WR_CMD, addr); |
---|
[5ece798] | 335 | |
---|
| 336 | CLOCKRATE_GET( &p ); |
---|
| 337 | i = p * ERASE_TIMEOUT_S; |
---|
| 338 | |
---|
[2a444594] | 339 | while ( STA_RDYRDY != (STA_RDYRDY & (sta = BSP_flashReadRaw(F_CMD_RD_STA, addr))) && --i > 0 ) { |
---|
| 340 | rtems_task_wake_after(1); |
---|
| 341 | } |
---|
| 342 | /* switch back to 'normal' mode */ |
---|
| 343 | (void)flash_array_mode_intel(b, addr); |
---|
| 344 | if ( 0 == i ) { |
---|
| 345 | fprintf(stderr,"Flash erase block: timeout\n"); |
---|
| 346 | return -1; |
---|
| 347 | } |
---|
| 348 | |
---|
| 349 | /* Verify */ |
---|
| 350 | for ( i = 0; i<b->fblksz; i++ ) { |
---|
| 351 | if ( (char)0xff != ((char*)addr)[i] ) { |
---|
| 352 | fprintf(stderr,"ERROR: Erase verification failed at %p\n", |
---|
| 353 | ((char*)addr) + i); |
---|
| 354 | return -1; |
---|
| 355 | } |
---|
| 356 | } |
---|
| 357 | return STA_RDYRDY == sta ? 0 : sta; |
---|
| 358 | } |
---|
| 359 | |
---|
| 360 | /* Unlock block holding 'addr'ess |
---|
[ac7af4a] | 361 | * |
---|
[2a444594] | 362 | * NOTES: - device switched back to array mode on exit. |
---|
| 363 | * - 'addr' must be 32-bit aligned. |
---|
| 364 | */ |
---|
| 365 | |
---|
| 366 | STATIC void |
---|
| 367 | flash_unlock_block_intel(struct bankdesc *b, uint32_t addr) |
---|
| 368 | { |
---|
| 369 | #ifdef DEBUG |
---|
| 370 | printf("Unlocking block 0x%08"PRIx32"\n", addr); |
---|
| 371 | #endif |
---|
| 372 | (void)BSP_flashReadRaw(F_CMD_WR_LCK, addr); |
---|
| 373 | (void)BSP_flashReadRaw(F_CMD_WR_CMD, addr); |
---|
| 374 | flash_pend(b, addr, TIMEOUT_US); |
---|
| 375 | } |
---|
| 376 | |
---|
| 377 | /* Lock block holding 'addr'ess |
---|
[ac7af4a] | 378 | * |
---|
[2a444594] | 379 | * NOTES: - device switched back to array mode on exit. |
---|
| 380 | * - 'addr' must be 32-bit aligned. |
---|
| 381 | */ |
---|
| 382 | |
---|
| 383 | STATIC void |
---|
| 384 | flash_lock_block_intel(struct bankdesc *b, uint32_t addr) |
---|
| 385 | { |
---|
| 386 | #ifdef DEBUG |
---|
| 387 | printf("Locking block 0x%08"PRIx32"\n", addr); |
---|
| 388 | #endif |
---|
| 389 | (void)BSP_flashReadRaw(F_CMD_WR_LCK, addr); |
---|
| 390 | (void)BSP_flashReadRaw(F_CMD_WR_LCK_SET, addr); |
---|
| 391 | flash_pend(b, addr, TIMEOUT_US); |
---|
| 392 | } |
---|
| 393 | |
---|
| 394 | STATIC uint32_t |
---|
| 395 | flash_write_line_intel(struct bankdesc *b, uint32_t a, char *s, uint32_t N) |
---|
| 396 | { |
---|
| 397 | uint32_t sta, Nspla, nxt, j; |
---|
| 398 | union { |
---|
| 399 | uint32_t u; |
---|
| 400 | char c[sizeof(uint32_t)]; |
---|
| 401 | } buf; |
---|
| 402 | |
---|
| 403 | /* address block */ |
---|
| 404 | if ( STA_RDYRDY != (sta = BSP_flashReadRaw(F_CMD_WR_BUF, a)) ) { |
---|
| 405 | return sta; |
---|
| 406 | } |
---|
| 407 | |
---|
| 408 | /* count per device */ |
---|
| 409 | N /= FLASH_STRIDE(b); |
---|
| 410 | |
---|
| 411 | /* splat out */ |
---|
| 412 | Nspla = (N<<8) | N; |
---|
| 413 | Nspla = (Nspla<<16) | Nspla; |
---|
| 414 | BSP_flashWriteRaw(Nspla - 0x01010101, a); |
---|
| 415 | |
---|
| 416 | /* fill buffer */ |
---|
| 417 | for (nxt = a; N>0; N--) { |
---|
| 418 | #if defined(TESTING) || (DEBUG > 4) |
---|
| 419 | printf("Writing DAT *0x%08"PRIx32" = 0x%08"PRIx32"\n", nxt, *(uint32_t*)s); |
---|
| 420 | #endif |
---|
| 421 | /* deal with misaligned sources */ |
---|
| 422 | for ( j=0; j<sizeof(buf.u); j++ ) { |
---|
| 423 | buf.c[j] = *s++; |
---|
| 424 | } |
---|
| 425 | *(A32)nxt = buf.u; |
---|
| 426 | nxt += FLASH_STRIDE(b); |
---|
| 427 | } |
---|
| 428 | |
---|
| 429 | BSP_flashReadRaw(F_CMD_WR_CMD, a); |
---|
| 430 | |
---|
| 431 | sta = flash_pend(b, a, TIMEOUT_US); |
---|
| 432 | |
---|
| 433 | return sta; |
---|
| 434 | } |
---|
| 435 | |
---|
| 436 | /* Query device for basic information verifying that we talk |
---|
| 437 | * to a 'known'/'supported' device. |
---|
[ac7af4a] | 438 | * |
---|
[2a444594] | 439 | * NOTES: - device switched back to array mode on exit. |
---|
| 440 | * - 'addr' must be 32-bit aligned. |
---|
| 441 | */ |
---|
| 442 | |
---|
| 443 | STATIC int |
---|
| 444 | flash_get_id_intel(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId) |
---|
| 445 | { |
---|
| 446 | uint16_t v,d; |
---|
| 447 | |
---|
| 448 | if ( 4 != FLASH_STRIDE(b) ) { |
---|
| 449 | fprintf(stderr,"intel flash programmer: Strides other than 4 not implemented yet\n"); |
---|
| 450 | return -1; |
---|
| 451 | } |
---|
| 452 | |
---|
| 453 | /* Try to read ID */ |
---|
| 454 | v = BSP_flashReadRaw(F_CMD_RD_ID, addr); |
---|
| 455 | d = BSP_flashReadRaw(F_CMD_RD_ID, addr + FLASH_STRIDE(b)); |
---|
| 456 | |
---|
| 457 | /* switch to array mode */ |
---|
| 458 | flash_array_mode_intel(b, addr); |
---|
| 459 | |
---|
| 460 | *pVendorId = v; |
---|
| 461 | *pDeviceId = d; |
---|
| 462 | |
---|
| 463 | return 0; |
---|
| 464 | } |
---|