📄 完成amdlv160d.txt
字号:
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#if defined(CONFIG_NIOS)
#include <nios.h>
#else
#include <asm/io.h>
#endif
#define UNLOCK_ADDR1 (unsigned short *) (0x555 << 1)
#define UNLOCK_ADDR2 (unsigned short *) (0x2aa << 1)
unsigned int SECTSZ[] = {(16 * 1024),(8 * 1024),(8 * 1024),(32 * 1024),(64 * 1024)};
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*----------------------------------------------------------------------*/
unsigned long flash_init (void)
{
int i;
unsigned long addr;
flash_info_t *fli = &flash_info[0];
fli->size = CFG_FLASH_SIZE;
fli->sector_count = CFG_MAX_FLASH_SECT;
fli->flash_id = FLASH_MAN_AMD + FLASH_AMDLV065D;
addr = CFG_FLASH_BASE;
for (i = 0; i < fli->sector_count; ++i) {
fli->start[i] = addr;
if(i<4)
addr += SECTSZ[i];
else
addr += SECTSZ[4];
fli->protect[i] = 0;
}
return (CFG_FLASH_SIZE);
}
/*--------------------------------------------------------------------*/
void flash_print_info (flash_info_t * info)
{
int i, k;
int erased;
unsigned long j;
unsigned long *addr;
writew (UNLOCK_ADDR1, 0xaa);
writew (UNLOCK_ADDR2, 0x55);
writew (UNLOCK_ADDR1, 0x90);
j = readw (0x01 << 1);
if(j == 8777)
{
printf(" FLASH ID is: %x\n The FLASH is: AMD29LV160D\n", j);
}
writew (0x0, 0xf0);
printf (" Size: %ld KB in %d Sectors\n",
info->size >> 10, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i)
{
/* Check if whole sector is erased */
erased = 1;
addr = (unsigned long *) info->start[i];
if(i<4)
{
for (k = 0; k < SECTSZ[i]/sizeof(unsigned long); k++)
{
if ( readl(addr++) != (unsigned long)-1)
{
erased = 0;
break;
}
}
/* Print the info */
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " ");
}
else
{
for (k = 0; k < SECTSZ[4]/sizeof(unsigned long); k++)
{
if ( readl(addr++) != (unsigned long)-1)
{
erased = 0;
break;
}
}
/* Print the info */
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s%s",
info->start[i],
erased ? " E" : " ",
info->protect[i] ? "RO " : " ");
}
}
printf ("\n");
}
/*-------------------------------------------------------------------*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
unsigned char *addr;
int prot, sect;
ulong start;
/* Some sanity checking */
if ((s_first < 0) || (s_first > s_last)) {
printf ("- no sectors to erase\n");
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
/* It's ok to erase multiple sectors provided we don't delay more
* than 50 usec between cmds ... at which point the erase time-out
* occurs. So don't go and put printf() calls in the loop ... it
* won't be very helpful ;-)
*/
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
addr = (unsigned char *) info->start[sect];
writew (UNLOCK_ADDR1, 0xaa);
writew (UNLOCK_ADDR2, 0x55);
writew (UNLOCK_ADDR1, 0x80);
writew (UNLOCK_ADDR1, 0xaa);
writew (UNLOCK_ADDR2, 0x55);
writew (addr, 0x30);
/* Now just wait for 0xff & provide some user
* feedback while we wait.
*/
start = get_timer (0);
while ( readw (addr) != 0xffff) {
udelay (1000 * 1000);
putc ('.');
if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
printf ("timeout\n");
return 1;
}
}
}
}
printf ("\n");
return 0;
}
/*-----------------------------------------------------------------------
* 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)
{
unsigned short *dst = (unsigned short *) addr;
unsigned short b;
ulong start;
unsigned short *p;
p = (unsigned short *) src;
while (cnt) {
/* Check for sufficient erase */
b = *p;
if ((readw (dst) & b) != b) {
printf ("%02x : %02x\n", readw (dst), b);
return (2);
}
writew (UNLOCK_ADDR1, 0xaa);
writew (UNLOCK_ADDR2, 0x55);
writew (UNLOCK_ADDR1, 0xa0);
writew (dst, b);
/* Verify write */
start = get_timer (0);
while (readw (dst) != b) {
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
return 1;
}
}
dst++;
p++;
cnt-=2;
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -