FreeCalypso > hg > fc-selenite
comparison src/cs/drivers/drv_app/ffs/board/drv.c @ 134:7d50d8d13711
FFS code sync with Magnetite + gcc version fix
This change brings the new flash autodetection for FC and Pirelli targets
from Magnetite, and should also fix the gcc version for C1xx and gtamodem
targets, which were previously broken because they used TI's original
flash autodetect code (which operates at address 0) while the boot ROM
is mapped there.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Dec 2018 08:43:25 +0000 |
parents | 4484ab3f6ab3 |
children | 7409b22cac61 |
comparison
equal
deleted
inserted
replaced
133:118c25581538 | 134:7d50d8d13711 |
---|---|
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 defined(__GNUC__) | |
986 /* | |
987 * This new FreeCalypso version of the device ID read function | |
988 * should work for all current targets, but we are being conservative | |
989 * and only enabling it for those targets for which it is required, | |
990 * i.e., where TI's original version does not work. | |
991 * | |
992 * Selenite change: for the gcc version we need to use this new | |
993 * autodetect code for all targets, TI's original version won't work | |
994 * because we run with the Calypso boot ROM at 0. | |
995 */ | |
996 | |
997 int addr, half, base, i; | |
998 | |
999 /* | |
1000 * We operate at a non-zero erase block boundary so that this ID read | |
1001 * operation will still work in our newer FreeCalypso environments | |
1002 * where we have the Calypso boot ROM mapped at 0. | |
1003 */ | |
1004 base = 0x40000; | |
1005 | |
1006 /* | |
1007 * muckery similar to TI's original to avoid literal pool loads, | |
1008 * but we produce and use 0xAAA and 0x554 offsets instead of TI's | |
1009 * original 0xAAAA and 0x5555. | |
1010 */ | |
1011 for (i = 0, addr = 0; i < 3; i++) | |
1012 addr = addr << 4 | 0xA; | |
1013 half = (addr >> 1) & ~1; | |
1014 | |
1015 FLASH_WRITE_HALFWORD (base + addr, 0xAA); | |
1016 FLASH_WRITE_HALFWORD (base + half, 0x55); | |
1017 FLASH_WRITE_HALFWORD (base + addr, 0x90); // Intel/AMD read id command | |
1018 | |
1019 *manufact = FLASH_READ_HALFWORD (base + 0); // flash a0 = 0 | |
1020 *device = FLASH_READ_HALFWORD (base + 2); // flash a0 = 1 | |
1021 | |
1022 // Read extended id | |
1023 device[1] = FLASH_READ_HALFWORD (base + (0xE << 1)); | |
1024 device[2] = FLASH_READ_HALFWORD (base + (0xF << 1)); | |
1025 FLASH_WRITE_HALFWORD (base, 0xFF); // Intel read-array command | |
1026 | |
1027 // AMD devices do not need the two unlock cycles but SST devices do, | |
1028 // even though the SST datasheets states otherwise ;-) | |
1029 FLASH_WRITE_HALFWORD (base + addr, 0xAA); | |
1030 FLASH_WRITE_HALFWORD (base + half, 0x55); | |
1031 FLASH_WRITE_HALFWORD (base + addr, 0xF0); // AMD read-array/reset command | |
1032 #else | |
1033 /* TI's original version */ | |
982 int addr, i; | 1034 int addr, i; |
983 | 1035 |
984 // This silly looking code has one purpose; to set addr = 0xAAAA. It is | 1036 // 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 | 1037 // necessary in order to force the compiler NOT to produce code that |
986 // uses LDR opcode(s) with PC-relative addressing. The assember code | 1038 // 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, | 1055 // AMD devices do not need the two unlock cycles but SST devices do, |
1004 // even though the SST datasheets states otherwise ;-) | 1056 // even though the SST datasheets states otherwise ;-) |
1005 FLASH_WRITE_HALFWORD (addr, 0xAA); | 1057 FLASH_WRITE_HALFWORD (addr, 0xAA); |
1006 FLASH_WRITE_HALFWORD (addr >> 1, 0x55); | 1058 FLASH_WRITE_HALFWORD (addr >> 1, 0x55); |
1007 FLASH_WRITE_HALFWORD (addr, 0xF0); // AMD read-array/reset command | 1059 FLASH_WRITE_HALFWORD (addr, 0xF0); // AMD read-array/reset command |
1060 #endif | |
1008 } | 1061 } |
1009 | 1062 |
1010 // Copy ffsdrv_device_id_read() function code to RAM. The only known way to | 1063 // 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 | 1064 // determine the size of the code is to look either in the linker-generated |
1012 // map file or in the assember output file. | 1065 // map file or in the assember output file. |
1119 ttw(ttr(TTrDrvOther, "}" NL)); | 1172 ttw(ttr(TTrDrvOther, "}" NL)); |
1120 | 1173 |
1121 return 0; | 1174 return 0; |
1122 } | 1175 } |
1123 | 1176 |
1177 #if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) | |
1178 | |
1179 #ifdef CONFIG_TARGET_FCFAM | |
1180 #define FLASH2_BASE_ADDR 0x01800000 | |
1181 #elif defined(CONFIG_TARGET_PIRELLI) | |
1182 #define FLASH2_BASE_ADDR 0x02000000 | |
1183 #endif | |
1184 | |
1185 int ffsdrv_is_new_spansion_flash(void) | |
1186 { | |
1187 uint16 cfi_hi, cfi_lo, cfi_ver; | |
1188 | |
1189 /* CFI query */ | |
1190 FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0x98); | |
1191 cfi_hi = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x86); | |
1192 cfi_lo = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x88); | |
1193 cfi_ver = (cfi_hi << 8) | (cfi_lo & 0xFF); | |
1194 | |
1195 /* return to read array mode */ | |
1196 FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0xF0); | |
1197 | |
1198 if (cfi_ver >= 0x3134) | |
1199 return 1; | |
1200 else | |
1201 return 0; | |
1202 } | |
1203 #endif | |
1204 | |
1124 #else // (TARGET == 0) | 1205 #else // (TARGET == 0) |
1125 | 1206 |
1126 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) {} | 1207 void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) {} |
1127 int ffsdrv_driver_copy_to_ram(int type) { return 0; } | 1208 int ffsdrv_driver_copy_to_ram(int type) { return 0; } |
1128 | 1209 |
1276 // If ffs_flash_device is zero, detect device automatically by copying | 1357 // If ffs_flash_device is zero, detect device automatically by copying |
1277 // the detect function into RAM and execute it from there... | 1358 // the detect function into RAM and execute it from there... |
1278 if (ffs_flash_manufact == 0 && ffs_flash_device == 0) | 1359 if (ffs_flash_manufact == 0 && ffs_flash_device == 0) |
1279 { | 1360 { |
1280 #if (TARGET == 1) | 1361 #if (TARGET == 1) |
1281 char detect_code[80]; | 1362 char detect_code[0x80]; |
1282 typedef (*pf_t)(uint16 *, uint16 *); | 1363 typedef (*pf_t)(uint16 *, uint16 *); |
1283 pf_t myfp; | 1364 pf_t myfp; |
1284 uint16 device_id[3]; | 1365 uint16 device_id[3]; |
1285 | 1366 |
1286 ffsdrv_device_id_read_copy_to_ram((uint16 *) detect_code, | 1367 ffsdrv_device_id_read_copy_to_ram((uint16 *) detect_code, |
1297 | 1378 |
1298 if ((dev.manufact == MANUFACT_AMD || dev.manufact == MANUFACT_FUJITSU) && | 1379 if ((dev.manufact == MANUFACT_AMD || dev.manufact == MANUFACT_FUJITSU) && |
1299 device_id[0] == 0x227E) { | 1380 device_id[0] == 0x227E) { |
1300 // This is a multi-id device | 1381 // This is a multi-id device |
1301 dev.device = (device_id[1] << 8) | (device_id[2] & 0xFF); | 1382 dev.device = (device_id[1] << 8) | (device_id[2] & 0xFF); |
1383 #if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) | |
1384 if (device_id[1] == 0x2221 && device_id[2] == 0x2200) | |
1385 dev.device += ffsdrv_is_new_spansion_flash(); | |
1386 #endif | |
1302 } | 1387 } |
1303 else | 1388 else |
1304 dev.device = device_id[0]; | 1389 dev.device = device_id[0]; |
1305 #endif | 1390 #endif |
1306 } | 1391 } |