changeset 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 118c25581538
children ac4c0a9bc022
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, 135 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/cs/drivers/drv_app/ffs/board/cfgffs.c	Mon Nov 19 07:19:05 2018 +0000
+++ b/src/cs/drivers/drv_app/ffs/board/cfgffs.c	Tue Dec 11 08:43:25 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 07:19:05 2018 +0000
+++ b/src/cs/drivers/drv_app/ffs/board/dev.c	Tue Dec 11 08:43:25 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 07:19:05 2018 +0000
+++ b/src/cs/drivers/drv_app/ffs/board/drv.c	Tue Dec 11 08:43:25 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,56 @@
 // 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) || \
+	defined(__GNUC__)
+    /*
+     * 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.
+     *
+     * Selenite change: for the gcc version we need to use this new
+     * autodetect code for all targets, TI's original version won't work
+     * because we run with the Calypso boot ROM at 0.
+     */
+
+    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 +1057,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 +1174,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 +1359,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];
@@ -1299,6 +1380,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];