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];