]> git.karo-electronics.de Git - karo-tx-redboot.git/blobdiff - packages/devs/flash/arm/mxc/v2_0/src/mxcflash_wrapper.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / flash / arm / mxc / v2_0 / src / mxcflash_wrapper.c
index dd59df0c878936524932509e0e78bcea6e3b0ae5..2afc642d6f09df8ad687ab699d29ec11a35e7b9b 100644 (file)
@@ -43,9 +43,9 @@
 // Author(s):    Kevin Zhang <k.zhang@freescale.com>
 // Contributors: Kevin Zhang <k.zhang@freescale.com>
 // Date:         2006-01-23
-// Purpose:      
-// Description:  
-//              
+// Purpose:
+// Description:
+//
 //####DESCRIPTIONEND####
 //
 //==========================================================================
@@ -73,19 +73,61 @@ extern int nandflash_erase_block(void* block, unsigned int size);
 extern int nandflash_program_buf(void* addr, void* data, int len);
 extern int nandflash_lock_block(void* block);
 extern int nandflash_unlock_block(void* block, int block_size, int blocks);
+extern void mxc_nfc_print_info(void);
+extern int nandflash_read_buf(void* addr, void* data, int len);
+
+extern void mmcflash_query(void* data);
+extern int mmcflash_hwr_init(void);
+extern int mmcflash_hwr_map_error(int e);
+extern bool mmcflash_code_overlaps(void *start, void *end);
+extern int mmcflash_erase_block(void* block, unsigned int size);
+extern int mmcflash_program_buf(void* addr, void* data, int len);
+extern int mmcflash_lock_block(void* block);
+extern int mmcflash_unlock_block(void* block, int block_size, int blocks);
+extern void mxc_mmc_print_info(void);
+extern int mmcflash_read_buf(void* addr, void* data, int len);
+
+extern void ata_hwr_init(void);
+
+extern void spi_norflash_query(void* data);
+extern int spi_norflash_hwr_init(void);
+extern int spi_norflash_hwr_map_error(int e);
+extern bool spi_norflash_code_overlaps(void *start, void *end);
+extern int spi_norflash_erase_block(void* block, unsigned int size);
+extern int spi_norflash_program_buf(void* addr, void* data, int len);
+extern int spi_norflash_lock_block(void* block);
+extern int spi_norflash_unlock_block(void* block, int block_size, int blocks);
+extern int spi_norflash_read_buf(void* addr, void* data, int len);
+
+#ifndef IS_BOOTING_FROM_SPI_NOR()
+#define IS_BOOTING_FROM_SPI_NOR()   0
+#endif
+#ifndef IS_FIS_FROM_SPI_NOR()
+#define IS_FIS_FROM_SPI_NOR()       0
+#endif
 
 static int mxc_flash_warning_done = 0;
 
 void flash_query(void* data)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         norflash_query(data);
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        spi_norflash_query(data);
+#endif
     } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
         nandflash_query(data);
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        mmcflash_query(data);
+#endif
     } else {
         if (!mxc_flash_warning_done) {
             mxc_flash_warning_done = 1;
-            diag_printf("1: Use \"factive [NOR|NAND]\" to select either NOR or NAND flash\n");
+            diag_printf("1: Use \"factive\" to select a boot type such as NAND|NOR|MMC|...\n");
         }
     }
 }
@@ -93,86 +135,215 @@ void flash_query(void* data)
 int flash_hwr_init(void)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_hwr_init();
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+#ifdef MXCFLASH_SELECT_ATA
+        /* ATA support is needed only for SPI boot */
+        ata_hwr_init();
+#endif
+        return spi_norflash_hwr_init();
+#endif
     } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_hwr_init();
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_hwr_init();
+#endif
     } else {
         if (!mxc_flash_warning_done)
             mxc_flash_warning_done = 1;
-        diag_printf("2: Use \"factive [NOR|NAND]\" to select either NOR or NAND flash\n");
+        diag_printf("2: Use \"factive\" to select a boot type such as NAND|NOR|MMC|...\n");
         return -1;
     }
+
+    return -1;
 }
 
 int flash_hwr_map_error(int e)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_hwr_map_error(e);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_hwr_map_error(e);
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        return spi_norflash_hwr_map_error(e);
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_hwr_map_error(e);
+#endif
     }
+    return e;
 }
 
 bool flash_code_overlaps(void *start, void *end)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_code_overlaps(start, end);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        return spi_norflash_code_overlaps(start, end);
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_code_overlaps(start, end);
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()){
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_code_overlaps(start, end);
+#endif
+    } else {
+        diag_printf("Error %d: where is fis\n", __LINE__);
+        return true;
     }
+    return false;
 }
 
 int flash_erase_block(void* block, unsigned int size)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_erase_block(block, size);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        return spi_norflash_erase_block(block, size);
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_erase_block(block, size);
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()){
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_erase_block(block, size);
+#endif
+    } else {
+        diag_printf("Error %d: where is fis\n", __LINE__);
+        return -1;
     }
+    return 0;
 }
 
 int flash_program_buf(void* addr, void* data, int len)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_program_buf(addr, data, len);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        return spi_norflash_program_buf(addr, data, len);
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_program_buf(addr, data, len);
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_program_buf(addr, data, len);
+#else
+        return 0;
+#endif
+    } else {
+        return -1;
+    }
+}
+
+int flash_read_buf(void* addr, void* data, int len)
+{
+    if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()){
+#ifdef MXCFLASH_SELECT_NAND
+        return nandflash_read_buf(addr, data, len);
+#endif
+    } else if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
+        memcpy(data, addr, len);
+        return 0;
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR() || IS_FIS_FROM_SPI_NOR()){
+#ifdef IMXFLASH_SELECT_SPI_NOR
+        return spi_nor_read(addr, data, len);
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()) {
+#ifdef MXCFLASH_SELECT_MMC
+       return mmcflash_read_buf(addr, data, len);
+#endif
+    } else {
+       return -1;
     }
+    return 0;
 }
 
 int flash_lock_block(void* block)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_lock_block(block);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_lock_block(block);
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_lock_block(block);
+#endif
     }
+    return 0;
 }
 
 int flash_unlock_block(void* block, int block_size, int blocks)
 {
     if (IS_BOOTING_FROM_NOR() || IS_FIS_FROM_NOR()) {
+#ifdef MXCFLASH_SELECT_NOR
         return norflash_unlock_block(block, block_size, blocks);
-    } else {
+#endif
+    } else if (IS_BOOTING_FROM_MMC() || IS_FIS_FROM_MMC()){
+#ifdef MXCFLASH_SELECT_MMC
+        return mmcflash_unlock_block(block, block_size, blocks);
+#endif
+    } else if (IS_BOOTING_FROM_NAND() || IS_FIS_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         return nandflash_unlock_block(block, block_size, blocks);
+#endif
     }
+    return 0;
 }
 
-extern void mxc_nfc_print_info(void);
-
 static void mxc_flash_print_info(void)
 {
     if (IS_BOOTING_FROM_NOR()) {
         diag_printf("\nBooting from [NOR flash]\n");
-        MXC_ASSERT_NOR_BOOT();
     } else if (IS_BOOTING_FROM_NAND()) {
+#ifdef MXCFLASH_SELECT_NAND
         diag_printf("\nBooting from [NAND flash]\n");
-        MXC_ASSERT_NAND_BOOT();
         mxc_nfc_print_info();
+#endif
+    } else if (IS_BOOTING_FROM_SPI_NOR()) {
+#ifdef MXCFLASH_SELECT_SPI_NOR
+        diag_printf("\nBooting from [SPI NOR flash]\n");
+        imx_spi_nor_print_info();
+#endif
     } else if (IS_BOOTING_FROM_SDRAM()) {
         diag_printf("\nBooting from [SDRAM]\n");
-    } else {
-        diag_printf("\n!!!Warning: Unknown boot source !!!\n");
+    } else if (IS_BOOTING_FROM_MMC() ){
+#ifdef MXCFLASH_SELECT_MMC
+        mxc_mmc_print_info();
+#else
+        return;
+#endif
     }
     diag_printf("\n");
 }