/*++
Copyright (c) 2013 WonderMedia Technologies, Inc.
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details. You
should have received a copy of the GNU General Public License along with this
program. If not, see http://www.gnu.org/licenses/>.
WonderMedia Technologies, Inc.
10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
--*/
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software Foundation,
* either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*
* WonderMedia Technologies, Inc.
* 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
*/
#include
#include
#include "flash/spi_flash.h"
#include "flash/nor_flash_8bit.h"
#include "flash/nor_flash_16bit.h"
/* #include "flash/nor_flash.h" */
#include "flash/nand_flash.h"
#include "include/extvars.h"
typedef enum _BOOT_FLASH_TYPE {
NOR_FLASH_TYPE = 0,
ROM_FLASH_TYPE,
NAND_FLASH_TYPE,
SPI_FLASH_TYPE,
MMC_FLASH_TYPE
} BOOT_FLASH_TYPE;
typedef enum _BOOT_BIT_TYPE {
BOOT_TYPE_8BIT = 0,
BOOT_TYPE_16BIT
} BOOT_BIT_TYPE;
BOOT_FLASH_TYPE flash_type = SPI_FLASH_TYPE;
BOOT_BIT_TYPE nor_flash_bit = BOOT_TYPE_16BIT;
BOOT_BIT_TYPE nand_flash_bit = BOOT_TYPE_16BIT;
flash_info_t flash_info_nor[CFG_MAX_NOR_FLASH_BANKS];
flash_info_t flash_info_spi[CFG_MAX_SPI_FLASH_BANKS];
flash_info_t flash_info_nand[CFG_MAX_NAND_FLASH_BANKS];
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
static unsigned int flash_count;
/*
* get_boot_flash_type()
*/
BOOT_FLASH_TYPE get_boot_flash_type(void)
{
unsigned int val = 0;
unsigned char rc = SPI_FLASH_TYPE;
val = *((volatile unsigned int *)(0xd8110100));
if ((val&(1<<14)) == 0)
rc = MMC_FLASH_TYPE;
else if (val&8)
rc = ROM_FLASH_TYPE;
else
rc = SPI_FLASH_TYPE;
return rc;
}
/*
* get_boot_nand_flash_bit_type()
*/
BOOT_BIT_TYPE get_boot_nand_flash_bit_type(void)
{
unsigned int val = 0;
unsigned char rc = BOOT_TYPE_8BIT;
val = *((volatile unsigned int *)(0xd8110100));
val = (val >> 4) & 0x1;
switch (val) {
case 0:
rc = BOOT_TYPE_8BIT;
break;
case 1:
rc = BOOT_TYPE_16BIT;
break;
default:
break;
}
return rc;
}
static void print_flash_addr(flash_info_t *info)
{
flash_info_t *p = NULL;
int i;
if (!flash_count)
return;
printf("flash:\n");
for (i = 0, p = info; flash_count != 0; p++, i++, flash_count--) {
printf(" Bank%d: %08lX -- %08lX", i+1, p->start[0], p->start[0]+p->size-1);
if (p->flash_id == FLASH_UNKNOWN)
printf(" (Missing or Unknown Flash)");
printf("\n");
}
}
/*
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init(void)
{
unsigned long rc = 0;
int i;
flash_type = get_boot_flash_type();
nand_flash_bit = get_boot_nand_flash_bit_type();
flash_count = 0;
/* because FLASH_UNKNOWN = 0XFFFffffF, SO WE USE FF INITIAL */
memset(flash_info, 0xff, CFG_MAX_FLASH_BANKS * sizeof(flash_info_t));
switch (flash_type) {
/*case NOR_FLASH_TYPE:
printf("boot from nor flash: ");
flash_count = CFG_MAX_NOR_FLASH_BANKS;
switch (nor_flash_bit) {
case BOOT_TYPE_8BIT:
printf("8bit mode.\n");
rc = nor_flash_8b_init();
break;
case BOOT_TYPE_16BIT:
printf("16bit mode.\n");
rc = nor_flash_16b_init();
break;
}
// rc = nor_flash_init();
for (i = 0; i < CFG_MAX_NOR_FLASH_BANKS; i++)
memcpy(&flash_info[i], &flash_info_nor[i], sizeof(flash_info_t));
break;*/
case NAND_FLASH_TYPE:
printf("boot from nand flash.\n");
flash_count = CFG_MAX_NAND_FLASH_BANKS;
rc = nand_flash_init();
for (i = 0; i < CFG_MAX_NAND_FLASH_BANKS; i++)
memcpy(&flash_info[i], &flash_info_nand[i], sizeof(flash_info_t));
break;
case SPI_FLASH_TYPE:
printf("boot from spi flash.\n");
flash_count = CFG_MAX_SPI_FLASH_BANKS;
rc = spi_flash_init();
for (i = 0; i < CFG_MAX_SPI_FLASH_BANKS; i++)
memcpy(&flash_info[i], &flash_info_spi[i], sizeof(flash_info_t));
break;
case ROM_FLASH_TYPE:
printf("boot from ROM.\n");
default:
printf("boot from unknow device====================\n");
break;
}
print_flash_addr(flash_info);
return rc;
}
/*
*/
void flash_print_info(flash_info_t *info)
{
switch (flash_type) {
#if 0
case NOR_FLASH_TYPE:
switch (nor_flash_bit) {
case BOOT_TYPE_8BIT:
nor_flash_8b_print_info(info);
break;
case BOOT_TYPE_16BIT:
nor_flash_16b_print_info(info);
break;
}
/* nor_flash_print_info(info); */
break;
#endif
case NAND_FLASH_TYPE:
nand_flash_print_info(info);
break;
case SPI_FLASH_TYPE:
spi_flash_print_info(info);
break;
default:
break;
}
}
/*
* flash_erase
*/
int flash_erase(flash_info_t *info, int s_first, int s_last)
{
int rc = 0;
switch (flash_type) {
#if 0
case NOR_FLASH_TYPE:
switch (nor_flash_bit) {
case BOOT_TYPE_8BIT:
rc = nor_flash_8b_erase(info, s_first, s_last);
break;
case BOOT_TYPE_16BIT:
rc = nor_flash_16b_erase(info, s_first, s_last);
break;
}
/* rc = nor_flash_erase(info, s_first, s_last); */
break;
#endif
case NAND_FLASH_TYPE:
rc = nand_flash_erase(info, s_first, s_last);
break;
case SPI_FLASH_TYPE:
/* sf boot, nand active */
rc = spi_flash_erase(info, s_first, s_last);
break;
default:
break;
}
return rc;
}
/*
* Copy flash to memory, returns:
* 0 - OK
* 1 - write timeout
*/
int read_buff(flash_info_t *info, ulong src, ulong addr, ulong cnt)
{
int rc = 0;
rc = spi_read_buff(info, src, addr, cnt);
return rc;
}
/*
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
int rc = 0;
switch (flash_type) {
#if 0
case NOR_FLASH_TYPE:
switch (nor_flash_bit) {
case BOOT_TYPE_8BIT:
rc = nor_flash_8b_write_buff(info, src, addr, cnt);
break;
case BOOT_TYPE_16BIT:
rc = nor_flash_16b_write_buff(info, src, addr, cnt);
break;
}
/* rc = nor_write_buff(info, src, addr, cnt); */
break;
#endif
case NAND_FLASH_TYPE:
rc = nand_write_buff(info, src, addr, cnt);
break;
case SPI_FLASH_TYPE:
/* sf boot, nand active */
rc = spi_write_buff(info, src, addr, cnt);
break;
default:
break;
}
return rc;
}
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
int rc = 0;
switch (flash_type) {
case NOR_FLASH_TYPE:
/* rc = nor_flash_real_protect(info, info->start[sector], prot); */
break;
case NAND_FLASH_TYPE:
/*rc = nand_flash_real_protect(info, info->start[sector], prot);*/
break;
case SPI_FLASH_TYPE:
/* sf boot, nand active */
rc = spi_flash_real_protect(info, sector, prot);
break;
default:
break;
}
return rc;
} /* end flash_real_protect() */