diff 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
line wrap: on
line diff
--- 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];