FreeCalypso > hg > fc-magnetite
changeset 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 | 39a226a06196 |
children | ddaa0263ea8e |
files | src/cs/drivers/drv_app/ffs/board/cfgffs.c src/cs/drivers/drv_app/ffs/board/dev.c src/cs/drivers/drv_app/ffs/board/drv.c |
diffstat | 3 files changed, 130 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cs/drivers/drv_app/ffs/board/cfgffs.c Mon Nov 19 02:00:21 2018 +0000 +++ b/src/cs/drivers/drv_app/ffs/board/cfgffs.c Tue Dec 11 07:37:44 2018 +0000 @@ -16,7 +16,6 @@ #include "ffs/board/drv.h" #include "config/board.cfg" -#include "config/fc-target.cfg" #if (BOARD == 34) #include "ffs/board/ffspcm.h" @@ -57,13 +56,6 @@ #else -#if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) - -uint16 ffs_flash_manufact = MANUFACT_AMD; -uint16 ffs_flash_device = 0x2101; - -#else - uint16 ffs_flash_manufact = 0x00; // autodetect device //uint16 ffs_flash_manufact = MANUFACT_RAM; //uint16 ffs_flash_manufact = 0x04; // Fujitsu @@ -75,8 +67,6 @@ //uint16 ffs_flash_device = 0x2761; // SST device 1601 //uint16 ffs_flash_device = 0x2259; // 8x8kB blocks -#endif - int ffs_ram_image_address = 0; // Dummy //unsigned char ffs_image[8*8*1024];
--- a/src/cs/drivers/drv_app/ffs/board/dev.c Mon Nov 19 02:00:21 2018 +0000 +++ b/src/cs/drivers/drv_app/ffs/board/dev.c Tue Dec 11 07:37:44 2018 +0000 @@ -128,7 +128,8 @@ }; #endif -#ifdef CONFIG_TARGET_LEONARDO +#if defined(CONFIG_TARGET_LEONARDO) || defined(CONFIG_TARGET_PIRELLI) || \ + defined(CONFIG_TARGET_FCFAM) // 128x64kb static const struct block_info_s flash_128x64[] = { @@ -359,20 +360,61 @@ #ifdef CONFIG_TARGET_PIRELLI - // Spansion S71PL129NC0 used in Pirelli DP-L10 - // ID made up (same as what Pirelli's fw uses), not using autodetect - // This is an aftermarket FFS config for the Pirelli target + /* + * Our familiar version of the Pirelli DP-L10 hw features Spansion + * S71PL129NC0HFW4B flash (N version, 256 KiB sectors), but apparently + * an earlier hw version had S71PL-J flash with 64 KiB sectors, + * and Pirelli's official fw supports both. They have modified + * TI's flash ID code to generate device ID 0x2100 for the J version + * or 0x2101 for the N version. We have now replicated this ID logic + * in our FreeCalypso code base, and we can now support both flash + * chip versions as well. + * + * Our FFS configuration for the Pirelli target is aftermarket. + */ + + /* J flash */ + { &flash_128x64[0], (char *) 0x02480000, MANUFACT_AMD, 0x2100, + FFS_DRIVER_AMD, 24 }, + + /* N flash */ { &flash_32x256[0], (char *) 0x02480000, MANUFACT_AMD, 0x2101, FFS_DRIVER_AMD, 6 }, #elif defined(CONFIG_TARGET_FCFAM) - // We are using the same flash+pSRAM chip in our own - // FreeCalypso hardware designs, but on a different chip select. - // Let's use the first 2 MiB of the 2nd bank for the FFS. + /* + * Our FreeCalypso hardware family is currently in its infancy + * (we have only one board design so far, but hoping to have more), + * thus the set of possible flash chip types on FC hw platforms + * is expected to grow. The footprint on our current FCDEV3B PCB + * ideally fits Spansion MCPs with two chip select banks (either + * S71PL-J or S71PL-N), but can also be fitted with Openmoko's + * Samsung K5A3281. Spansion S71PL129NC0HFW4B (copied from the + * Pirelli DP-L10) is our official flash+RAM chip, populated on + * our production boards, but now that we have fixed TI's autodetect + * code to work with the newer Spansion chips, we can support + * all 3 possibilities in our fw with autodetection: S71PL-J, + * S71PL-N or K5A32xx. + * + * For future FreeCalypso hw designs, the Mother's plan is to + * keep the high-capacity S71PL129NC0HFW4B for the handset prototype + * and UI development board, but for embedded modem products + * we will probably switch to Openmoko's K5A32xx. + */ + + /* S71PL-N, FreeCalypso official, FFS in the first 2 MiB of the 2nd bank */ { &flash_32x256[0], (char *) 0x01800000, MANUFACT_AMD, 0x2101, FFS_DRIVER_AMD, 8 }, + /* S71PL-J, currently only theoretical */ + { &flash_128x64[0], (char *) 0x01800000, MANUFACT_AMD, 0x2100, + FFS_DRIVER_AMD, 32 }, + + /* K5A32xxCTM from Openmoko */ + { &flash_16x64[0], (char *) 0x380000, MANUFACT_SAMSUNG, 0x22A0, + FFS_DRIVER_AMD, 7 }, + #elif defined(CONFIG_TARGET_COMPAL) /* aftermarket FFS configurations for FreeCalypso on Mot C1xx phones */
--- a/src/cs/drivers/drv_app/ffs/board/drv.c Mon Nov 19 02:00:21 2018 +0000 +++ b/src/cs/drivers/drv_app/ffs/board/drv.c Tue Dec 11 07:37:44 2018 +0000 @@ -12,6 +12,8 @@ #include "ffs.cfg" #endif +#include "fc-target.cfg" + #include "ffs/ffs.h" #include "ffs/board/drv.h" #include "ffs/board/ffstrace.h" @@ -979,6 +981,51 @@ // The function should be copied and executed from RAM! void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) { +#if defined(CONFIG_TARGET_FCFAM) || defined(CONFIG_TARGET_PIRELLI) + /* + * This new FreeCalypso version of the device ID read function + * should work for all current targets, but we are being conservative + * and only enabling it for those targets for which it is required, + * i.e., where TI's original version does not work. + */ + + int addr, half, base, i; + + /* + * We operate at a non-zero erase block boundary so that this ID read + * operation will still work in our newer FreeCalypso environments + * where we have the Calypso boot ROM mapped at 0. + */ + base = 0x40000; + + /* + * muckery similar to TI's original to avoid literal pool loads, + * but we produce and use 0xAAA and 0x554 offsets instead of TI's + * original 0xAAAA and 0x5555. + */ + for (i = 0, addr = 0; i < 3; i++) + addr = addr << 4 | 0xA; + half = (addr >> 1) & ~1; + + FLASH_WRITE_HALFWORD (base + addr, 0xAA); + FLASH_WRITE_HALFWORD (base + half, 0x55); + FLASH_WRITE_HALFWORD (base + addr, 0x90); // Intel/AMD read id command + + *manufact = FLASH_READ_HALFWORD (base + 0); // flash a0 = 0 + *device = FLASH_READ_HALFWORD (base + 2); // flash a0 = 1 + + // Read extended id + device[1] = FLASH_READ_HALFWORD (base + (0xE << 1)); + device[2] = FLASH_READ_HALFWORD (base + (0xF << 1)); + FLASH_WRITE_HALFWORD (base, 0xFF); // Intel read-array command + + // AMD devices do not need the two unlock cycles but SST devices do, + // even though the SST datasheets states otherwise ;-) + FLASH_WRITE_HALFWORD (base + addr, 0xAA); + FLASH_WRITE_HALFWORD (base + half, 0x55); + FLASH_WRITE_HALFWORD (base + addr, 0xF0); // AMD read-array/reset command +#else + /* TI's original version */ int addr, i; // This silly looking code has one purpose; to set addr = 0xAAAA. It is @@ -1005,6 +1052,7 @@ FLASH_WRITE_HALFWORD (addr, 0xAA); FLASH_WRITE_HALFWORD (addr >> 1, 0x55); FLASH_WRITE_HALFWORD (addr, 0xF0); // AMD read-array/reset command +#endif } // Copy ffsdrv_device_id_read() function code to RAM. The only known way to @@ -1121,6 +1169,34 @@ return 0; } +#if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) + +#ifdef CONFIG_TARGET_FCFAM +#define FLASH2_BASE_ADDR 0x01800000 +#elif defined(CONFIG_TARGET_PIRELLI) +#define FLASH2_BASE_ADDR 0x02000000 +#endif + +int ffsdrv_is_new_spansion_flash(void) +{ + uint16 cfi_hi, cfi_lo, cfi_ver; + + /* CFI query */ + FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0x98); + cfi_hi = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x86); + cfi_lo = FLASH_READ_HALFWORD(FLASH2_BASE_ADDR + 0x88); + cfi_ver = (cfi_hi << 8) | (cfi_lo & 0xFF); + + /* return to read array mode */ + FLASH_WRITE_HALFWORD(FLASH2_BASE_ADDR + 0xAAA, 0xF0); + + if (cfi_ver >= 0x3134) + return 1; + else + return 0; +} +#endif + #else // (TARGET == 0) void ffsdrv_device_id_read(uint16 *manufact, uint16 *device) {} @@ -1278,7 +1354,7 @@ if (ffs_flash_manufact == 0 && ffs_flash_device == 0) { #if (TARGET == 1) - char detect_code[80]; + char detect_code[0x80]; typedef (*pf_t)(uint16 *, uint16 *); pf_t myfp; uint16 device_id[3]; @@ -1294,6 +1370,10 @@ device_id[0] == 0x227E) { // This is a multi-id device dev.device = (device_id[1] << 8) | (device_id[2] & 0xFF); + #if defined(CONFIG_TARGET_PIRELLI) || defined(CONFIG_TARGET_FCFAM) + if (device_id[1] == 0x2221 && device_id[2] == 0x2200) + dev.device += ffsdrv_is_new_spansion_flash(); + #endif } else dev.device = device_id[0];