FreeCalypso > hg > fc-magnetite
comparison src/cs/drivers/drv_app/ffs/board/drv.c @ 557:7aad22344e77
flash autodetection made to work on FC and Pirelli targets
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Dec 2018 07:37:44 +0000 |
parents | 204d6866901b |
children | 92dbfa906f66 |
comparison
equal
deleted
inserted
replaced
556:39a226a06196 | 557:7aad22344e77 |
---|---|
9 ******************************************************************************/ | 9 ******************************************************************************/ |
10 | 10 |
11 #ifndef TARGET | 11 #ifndef TARGET |
12 #include "ffs.cfg" | 12 #include "ffs.cfg" |
13 #endif | 13 #endif |
14 | |
15 #include "fc-target.cfg" | |
14 | 16 |
15 #include "ffs/ffs.h" | 17 #include "ffs/ffs.h" |
16 #include "ffs/board/drv.h" | 18 #include "ffs/board/drv.h" |
17 #include "ffs/board/ffstrace.h" | 19 #include "ffs/board/ffstrace.h" |
18 | 20 |
977 // families; Intel, AMD and SST. This works because Intel and AMD use | 979 // families; Intel, AMD and SST. This works because Intel and AMD use |
978 // the same command data for entering READ_IDENTIFIER mode (0x90). | 980 // the same command data for entering READ_IDENTIFIER mode (0x90). |
979 // The function should be copied and executed from RAM! | 981 // The function should be copied and executed from RAM! |
980 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) | 982 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) |
981 { | 983 { |
984 #if defined(CONFIG_TARGET_FCFAM) || defined(CONFIG_TARGET_PIRELLI) | |
985 /* | |
986 * This new FreeCalypso version of the device ID read function | |
987 * should work for all current targets, but we are being conservative | |
988 * and only enabling it for those targets for which it is required, | |
989 * i.e., where TI's original version does not work. | |
990 */ | |
991 | |
992 int addr, half, base, i; | |
993 | |
994 /* | |
995 * We operate at a non-zero erase block boundary so that this ID read | |
996 * operation will still work in our newer FreeCalypso environments | |
997 * where we have the Calypso boot ROM mapped at 0. | |
998 */ | |
999 base = 0x40000; | |
1000 | |
1001 /* | |
1002 * muckery similar to TI's original to avoid literal pool loads, | |
1003 * but we produce and use 0xAAA and 0x554 offsets instead of TI's | |
1004 * original 0xAAAA and 0x5555. | |
1005 */ | |
1006 for (i = 0, addr = 0; i < 3; i++) | |
1007 addr = addr << 4 | 0xA; | |
1008 half = (addr >> 1) & ~1; | |
1009 | |
1010 FLASH_WRITE_HALFWORD (base + addr, 0xAA); | |
1011 FLASH_WRITE_HALFWORD (base + half, 0x55); | |
1012 FLASH_WRITE_HALFWORD (base + addr, 0x90); // Intel/AMD read id command | |
1013 | |
1014 *manufact = FLASH_READ_HALFWORD (base + 0); // flash a0 = 0 | |
1015 *device = FLASH_READ_HALFWORD (base + 2); // flash a0 = 1 | |
1016 | |
1017 // Read extended id | |
1018 device[1] = FLASH_READ_HALFWORD (base + (0xE << 1)); | |
1019 device[2] = FLASH_READ_HALFWORD (base + (0xF << 1)); | |
1020 FLASH_WRITE_HALFWORD (base, 0xFF); // Intel read-array command | |
1021 | |
1022 // AMD devices do not need the two unlock cycles but SST devices do, | |
1023 // even though the SST datasheets states otherwise ;-) | |
1024 FLASH_WRITE_HALFWORD (base + addr, 0xAA); | |
1025 FLASH_WRITE_HALFWORD (base + half, 0x55); | |
1026 FLASH_WRITE_HALFWORD (base + addr, 0xF0); // AMD read-array/reset command | |
1027 #else | |
1028 /* TI's original version */ | |
982 int addr, i; | 1029 int addr, i; |
983 | 1030 |
984 // This silly looking code has one purpose; to set addr = 0xAAAA. It is | 1031 // This silly looking code has one purpose; to set addr = 0xAAAA. It is |
985 // necessary in order to force the compiler NOT to produce code that | 1032 // necessary in order to force the compiler NOT to produce code that |
986 // uses LDR opcode(s) with PC-relative addressing. The assember code | 1033 // uses LDR opcode(s) with PC-relative addressing. The assember code |
1003 // AMD devices do not need the two unlock cycles but SST devices do, | 1050 // AMD devices do not need the two unlock cycles but SST devices do, |
1004 // even though the SST datasheets states otherwise ;-) | 1051 // even though the SST datasheets states otherwise ;-) |
1005 FLASH_WRITE_HALFWORD (addr, 0xAA); | 1052 FLASH_WRITE_HALFWORD (addr, 0xAA); |
1006 FLASH_WRITE_HALFWORD (addr >> 1, 0x55); | 1053 FLASH_WRITE_HALFWORD (addr >> 1, 0x55); |
1007 FLASH_WRITE_HALFWORD (addr, 0xF0); // AMD read-array/reset command | 1054 FLASH_WRITE_HALFWORD (addr, 0xF0); // AMD read-array/reset command |
1055 #endif | |
1008 } | 1056 } |
1009 | 1057 |
1010 // Copy ffsdrv_device_id_read() function code to RAM. The only known way to | 1058 // Copy ffsdrv_device_id_read() function code to RAM. The only known way to |
1011 // determine the size of the code is to look either in the linker-generated | 1059 // determine the size of the code is to look either in the linker-generated |
1012 // map file or in the assember output file. | 1060 // map file or in the assember output file. |
1119 ttw(ttr(TTrDrvOther, "}" NL)); | 1167 ttw(ttr(TTrDrvOther, "}" NL)); |
1120 | 1168 |
1121 return 0; | 1169 return 0; |
1122 } | 1170 } |
1123 | 1171 |
1172 #if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) | |
1173 | |
1174 #ifdef CONFIG_TARGET_FCFAM | |
1175 #define FLASH2_BASE_ADDR 0x01800000 | |
1176 #elif defined(CONFIG_TARGET_PIRELLI) | |
1177 #define FLASH2_BASE_ADDR 0x02000000 | |
1178 #endif | |
1179 | |
1180 int ffsdrv_is_new_spansion_flash(void) | |
1181 { | |
1182 uint16 cfi_hi, cfi_lo, cfi_ver; | |
1183 | |
1184 /* CFI query */ | |
1185 FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0x98); | |
1186 cfi_hi = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x86); | |
1187 cfi_lo = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x88); | |
1188 cfi_ver = (cfi_hi << 8) | (cfi_lo & 0xFF); | |
1189 | |
1190 /* return to read array mode */ | |
1191 FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0xF0); | |
1192 | |
1193 if (cfi_ver >= 0x3134) | |
1194 return 1; | |
1195 else | |
1196 return 0; | |
1197 } | |
1198 #endif | |
1199 | |
1124 #else // (TARGET == 0) | 1200 #else // (TARGET == 0) |
1125 | 1201 |
1126 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) {} | 1202 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) {} |
1127 int ffsdrv_driver_copy_to_ram(int type) { return 0; } | 1203 int ffsdrv_driver_copy_to_ram(int type) { return 0; } |
1128 | 1204 |
1276 // If ffs_flash_device is zero, detect device automatically by copying | 1352 // If ffs_flash_device is zero, detect device automatically by copying |
1277 // the detect function into RAM and execute it from there... | 1353 // the detect function into RAM and execute it from there... |
1278 if (ffs_flash_manufact == 0 && ffs_flash_device == 0) | 1354 if (ffs_flash_manufact == 0 && ffs_flash_device == 0) |
1279 { | 1355 { |
1280 #if (TARGET == 1) | 1356 #if (TARGET == 1) |
1281 char detect_code[80]; | 1357 char detect_code[0x80]; |
1282 typedef (*pf_t)(uint16 *, uint16 *); | 1358 typedef (*pf_t)(uint16 *, uint16 *); |
1283 pf_t myfp; | 1359 pf_t myfp; |
1284 uint16 device_id[3]; | 1360 uint16 device_id[3]; |
1285 | 1361 |
1286 ffsdrv_device_id_read_copy_to_ram((uint16 *) detect_code, | 1362 ffsdrv_device_id_read_copy_to_ram((uint16 *) detect_code, |
1292 | 1368 |
1293 if ((dev.manufact == MANUFACT_AMD || dev.manufact == MANUFACT_FUJITSU) && | 1369 if ((dev.manufact == MANUFACT_AMD || dev.manufact == MANUFACT_FUJITSU) && |
1294 device_id[0] == 0x227E) { | 1370 device_id[0] == 0x227E) { |
1295 // This is a multi-id device | 1371 // This is a multi-id device |
1296 dev.device = (device_id[1] << 8) | (device_id[2] & 0xFF); | 1372 dev.device = (device_id[1] << 8) | (device_id[2] & 0xFF); |
1373 #if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) | |
1374 if (device_id[1] == 0x2221 && device_id[2] == 0x2200) | |
1375 dev.device += ffsdrv_is_new_spansion_flash(); | |
1376 #endif | |
1297 } | 1377 } |
1298 else | 1378 else |
1299 dev.device = device_id[0]; | 1379 dev.device = device_id[0]; |
1300 #endif | 1380 #endif |
1301 } | 1381 } |