]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_eeprom.c
hammerhead/mimc200: Use CONFIG_FLASH_CFI_DRIVER
[karo-tx-uboot.git] / common / cmd_eeprom.c
index 3db0bca69dab8ff7744f144e59bf4415bb71d363..e5000e9ff399f43dc21ab1015592f7f9cacf2aed 100644 (file)
  *
  */
 
+/*
+ * Support for read and write access to EEPROM like memory devices. This
+ * includes regular EEPROM as well as  FRAM (ferroelectic nonvolaile RAM).
+ * FRAM devices read and write data at bus speed. In particular, there is no
+ * write delay. Also, there is no limit imposed on the numer of bytes that can
+ * be transferred with a single read or write.
+ *
+ * Use the following configuration options to ensure no unneeded performance
+ * degradation (typical for EEPROM) is incured for FRAM memory:
+ *
+ * #define CFG_I2C_FRAM
+ * #undef CFG_EEPROM_PAGE_WRITE_DELAY_MS
+ *
+ */
+
 #include <common.h>
 #include <config.h>
 #include <command.h>
 #include <i2c.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
+#if defined(CFG_ENV_IS_IN_EEPROM) || defined(CONFIG_CMD_EEPROM)
 
 extern void eeprom_init  (void);
 extern int  eeprom_read  (unsigned dev_addr, unsigned offset,
                          uchar *buffer, unsigned cnt);
 extern int  eeprom_write (unsigned dev_addr, unsigned offset,
                          uchar *buffer, unsigned cnt);
+#if defined(CFG_EEPROM_WREN)
+extern int eeprom_write_enable (unsigned dev_addr, int state);
+#endif
 #endif
 
 
@@ -44,7 +62,7 @@ extern int  eeprom_write (unsigned dev_addr, unsigned offset,
 
 /* ------------------------------------------------------------------------- */
 
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
+#if defined(CONFIG_CMD_EEPROM)
 int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
        const char *const fmt =
@@ -75,7 +93,7 @@ int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
                        rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt);
 
-                       printf ("done\n");
+                       puts ("done\n");
                        return rcode;
                } else if (strcmp (argv[1], "write") == 0) {
                        int rcode;
@@ -84,7 +102,7 @@ int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 
                        rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt);
 
-                       printf ("done\n");
+                       puts ("done\n");
                        return rcode;
                }
        }
@@ -92,7 +110,7 @@ int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        printf ("Usage:\n%s\n", cmdtp->usage);
        return 1;
 }
-#endif /* CFG_CMD_EEPROM */
+#endif
 
 /*-----------------------------------------------------------------------
  *
@@ -103,7 +121,7 @@ int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  *   0x00000nxx for EEPROM address selectors and page number at n.
  */
 
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
+#if defined(CFG_ENV_IS_IN_EEPROM) || defined(CONFIG_CMD_EEPROM)
 
 #ifndef CONFIG_SPI
 #if !defined(CFG_I2C_EEPROM_ADDR_LEN) || CFG_I2C_EEPROM_ADDR_LEN < 1 || CFG_I2C_EEPROM_ADDR_LEN > 2
@@ -122,7 +140,11 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt
         * because the next page may be in a different device.
         */
        while (offset < end) {
-               unsigned alen, len, maxlen;
+               unsigned alen, len;
+#if !defined(CFG_I2C_FRAM)
+               unsigned maxlen;
+#endif
+
 #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
                uchar addr[2];
 
@@ -144,12 +166,21 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt
 
                addr[0] |= dev_addr;            /* insert device address */
 
+               len = end - offset;
+
+               /*
+                * For a FRAM device there is no limit on the number of the
+                * bytes that can be ccessed with the single read or write
+                * operation.
+                */
+#if !defined(CFG_I2C_FRAM)
                maxlen = 0x100 - blk_off;
                if (maxlen > I2C_RXTX_LEN)
                        maxlen = I2C_RXTX_LEN;
-               len    = end - offset;
                if (len > maxlen)
                        len = maxlen;
+#endif
+
 #ifdef CONFIG_SPI
                spi_read (addr, alen, buffer, len);
 #else
@@ -159,6 +190,7 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt
                buffer += len;
                offset += len;
        }
+
        return rcode;
 }
 
@@ -185,13 +217,20 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
        int     i;
 #endif
 
+#if defined(CFG_EEPROM_WREN)
+       eeprom_write_enable (dev_addr,1);
+#endif
        /* Write data until done or would cross a write page boundary.
         * We must write the address again when changing pages
         * because the address counter only increments within a page.
         */
 
        while (offset < end) {
-               unsigned alen, len, maxlen;
+               unsigned alen, len;
+#if !defined(CFG_I2C_FRAM)
+               unsigned maxlen;
+#endif
+
 #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
                uchar addr[2];
 
@@ -213,6 +252,15 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
 
                addr[0] |= dev_addr;            /* insert device address */
 
+               len = end - offset;
+
+               /*
+                * For a FRAM device there is no limit on the number of the
+                * bytes that can be ccessed with the single read or write
+                * operation.
+                */
+#if !defined(CFG_I2C_FRAM)
+
 #if defined(CFG_EEPROM_PAGE_WRITE_BITS)
 
 #define        EEPROM_PAGE_SIZE        (1 << CFG_EEPROM_PAGE_WRITE_BITS)
@@ -225,9 +273,10 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
                if (maxlen > I2C_RXTX_LEN)
                        maxlen = I2C_RXTX_LEN;
 
-               len = end - offset;
                if (len > maxlen)
                        len = maxlen;
+#endif
+
 #ifdef CONFIG_SPI
                spi_write (addr, alen, buffer, len);
 #else
@@ -295,7 +344,7 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
 #endif
                        }
                        if (i == MAX_ACKNOWLEDGE_POLLS) {
-                               printf("EEPROM poll acknowledge failed\n");
+                               puts ("EEPROM poll acknowledge failed\n");
                                rcode = 1;
                        }
                }
@@ -324,6 +373,9 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
                udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
 #endif
        }
+#if defined(CFG_EEPROM_WREN)
+       eeprom_write_enable (dev_addr,0);
+#endif
        return rcode;
 }
 
@@ -370,4 +422,28 @@ void eeprom_init  (void)
 }
 /*-----------------------------------------------------------------------
  */
-#endif /* CFG_CMD_EEPROM */
+#endif
+
+/***************************************************/
+
+#if defined(CONFIG_CMD_EEPROM)
+
+#ifdef CFG_I2C_MULTI_EEPROMS
+U_BOOT_CMD(
+       eeprom, 6,      1,      do_eeprom,
+       "eeprom  - EEPROM sub-system\n",
+       "read  devaddr addr off cnt\n"
+       "eeprom write devaddr addr off cnt\n"
+       "       - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'\n"
+);
+#else /* One EEPROM */
+U_BOOT_CMD(
+       eeprom, 5,      1,      do_eeprom,
+       "eeprom  - EEPROM sub-system\n",
+       "read  addr off cnt\n"
+       "eeprom write addr off cnt\n"
+       "       - read/write `cnt' bytes at EEPROM offset `off'\n"
+);
+#endif /* CFG_I2C_MULTI_EEPROMS */
+
+#endif