// Author(s): Kevin Zhang <k.zhang@freescale.com>
// Contributors: Kevin Zhang <k.zhang@freescale.com>
// Date: 2006-01-23
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
//####DESCRIPTIONEND####
//
//==========================================================================
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");
}
}
}
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");
}