diff src/cs/drivers/drv_app/ffs/board/drv.c @ 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 204d6866901b
children 92dbfa906f66
line wrap: on
line diff
--- 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];