aboutsummaryrefslogtreecommitdiff
path: root/board/cpc45/flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/cpc45/flash.c')
-rw-r--r--board/cpc45/flash.c311
1 files changed, 170 insertions, 141 deletions
diff --git a/board/cpc45/flash.c b/board/cpc45/flash.c
index 904923543..37dd182ba 100644
--- a/board/cpc45/flash.c
+++ b/board/cpc45/flash.c
@@ -41,12 +41,12 @@
#define MAIN_SECT_SIZE 0x40000
#define PARAM_SECT_SIZE 0x8000
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
-static int write_data (flash_info_t *info, ulong dest, ulong *data);
-static void write_via_fpu(vu_long *addr, ulong *data);
-static __inline__ unsigned long get_msr(void);
-static __inline__ void set_msr(unsigned long msr);
+static int write_data (flash_info_t * info, ulong dest, ulong * data);
+static void write_via_fpu (vu_long * addr, ulong * data);
+static __inline__ unsigned long get_msr (void);
+static __inline__ void set_msr (unsigned long msr);
/*---------------------------------------------------------------------*/
#undef DEBUG_FLASH
@@ -62,102 +62,132 @@ static __inline__ void set_msr(unsigned long msr);
/*-----------------------------------------------------------------------
*/
-unsigned long flash_init(void)
+unsigned long flash_init (void)
{
- int i, j;
- ulong size = 0;
- uchar tempChar;
+ int i, j;
+ ulong size = 0;
+ uchar tempChar;
+ vu_long *tmpaddr;
- /* Enable flash writes on CPC45 */
+ /* Enable flash writes on CPC45 */
- tempChar = BOARD_CTRL;
+ tempChar = BOARD_CTRL;
- tempChar |= (B_CTRL_FWPT_1 | B_CTRL_FWRE_1);
+ tempChar |= (B_CTRL_FWPT_1 | B_CTRL_FWRE_1);
- tempChar &= ~(B_CTRL_FWPT_0 | B_CTRL_FWRE_0);
+ tempChar &= ~(B_CTRL_FWPT_0 | B_CTRL_FWRE_0);
- BOARD_CTRL = tempChar;
+ BOARD_CTRL = tempChar;
+ __asm__ volatile ("sync\n eieio");
- for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
- vu_long *addr = (vu_long *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE);
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ vu_long *addr = (vu_long *) (CFG_FLASH_BASE + i * FLASH_BANK_SIZE);
- addr[0] = 0x00900090;
+ addr[0] = 0x00900090;
- DEBUGF ("Flash bank # %d:\n"
- "\tManuf. ID @ 0x%08lX: 0x%08lX\n"
- "\tDevice ID @ 0x%08lX: 0x%08lX\n",
- i,
- (ulong)(&addr[0]), addr[0],
- (ulong)(&addr[2]), addr[2]);
+ __asm__ volatile ("sync\n eieio");
+ udelay (100);
- if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) &&
- (addr[2] == addr[3]) && (addr[2] == INTEL_ID_28F160F3T))
- {
+ DEBUGF ("Flash bank # %d:\n"
+ "\tManuf. ID @ 0x%08lX: 0x%08lX\n"
+ "\tDevice ID @ 0x%08lX: 0x%08lX\n",
+ i,
+ (ulong) (&addr[0]), addr[0],
+ (ulong) (&addr[2]), addr[2]);
- flash_info[i].flash_id = (FLASH_MAN_INTEL & FLASH_VENDMASK) |
- (INTEL_ID_28F160F3T & FLASH_TYPEMASK);
- } else {
- flash_info[i].flash_id = FLASH_UNKNOWN;
- addr[0] = 0xFFFFFFFF;
- goto Done;
- }
+ if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT) &&
+ (addr[2] == addr[3]) && (addr[2] == INTEL_ID_28F160F3T)) {
- DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
+ flash_info[i].flash_id =
+ (FLASH_MAN_INTEL & FLASH_VENDMASK) |
+ (INTEL_ID_28F160F3T & FLASH_TYPEMASK);
- addr[0] = 0xFFFFFFFF;
+ } else if ((addr[0] == addr[1]) && (addr[0] == INTEL_MANUFACT)
+ && (addr[2] == addr[3])
+ && (addr[2] == INTEL_ID_28F160C3T)) {
+
+ flash_info[i].flash_id =
+ (FLASH_MAN_INTEL & FLASH_VENDMASK) |
+ (INTEL_ID_28F160C3T & FLASH_TYPEMASK);
- flash_info[i].size = FLASH_BANK_SIZE;
- flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
- memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
- for (j = 0; j < flash_info[i].sector_count; j++) {
- if (j > 30) {
- flash_info[i].start[j] = CFG_FLASH_BASE +
- i * FLASH_BANK_SIZE +
- (MAIN_SECT_SIZE * 31) + (j - 31) * PARAM_SECT_SIZE;
} else {
- flash_info[i].start[j] = CFG_FLASH_BASE +
- i * FLASH_BANK_SIZE +
- j * MAIN_SECT_SIZE;
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ addr[0] = 0xFFFFFFFF;
+ goto Done;
+ }
+
+ DEBUGF ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
+
+ addr[0] = 0xFFFFFFFF;
+
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+ memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ if (j > 30) {
+ flash_info[i].start[j] = CFG_FLASH_BASE +
+ i * FLASH_BANK_SIZE +
+ (MAIN_SECT_SIZE * 31) + (j -
+ 31) *
+ PARAM_SECT_SIZE;
+ } else {
+ flash_info[i].start[j] = CFG_FLASH_BASE +
+ i * FLASH_BANK_SIZE +
+ j * MAIN_SECT_SIZE;
+ }
+ }
+
+ /* unlock sectors, if 160C3T */
+
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ tmpaddr = (vu_long *) flash_info[i].start[j];
+
+ if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+ (INTEL_ID_28F160C3T & FLASH_TYPEMASK)) {
+ tmpaddr[0] = 0x00600060;
+ tmpaddr[0] = 0x00D000D0;
+ tmpaddr[1] = 0x00600060;
+ tmpaddr[1] = 0x00D000D0;
+ }
}
+
+ size += flash_info[i].size;
+
+ addr[0] = 0x00FF00FF;
+ addr[1] = 0x00FF00FF;
}
- size += flash_info[i].size;
- }
- /* Protect monitor and environment sectors
- */
-#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+ /* Protect monitor and environment sectors
+ */
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE + FLASH_BANK_SIZE
- flash_protect(FLAG_PROTECT_SET,
- CFG_MONITOR_BASE,
- CFG_MONITOR_BASE + monitor_flash_len - 1,
- &flash_info[1]);
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + monitor_flash_len - 1,
+ &flash_info[1]);
#else
- flash_protect(FLAG_PROTECT_SET,
- CFG_MONITOR_BASE,
- CFG_MONITOR_BASE + monitor_flash_len - 1,
- &flash_info[0]);
-#endif
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + monitor_flash_len - 1,
+ &flash_info[0]);
#endif
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
#if CFG_ENV_ADDR >= CFG_FLASH_BASE + FLASH_BANK_SIZE
- flash_protect(FLAG_PROTECT_SET,
- CFG_ENV_ADDR,
- CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
- &flash_info[1]);
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[1]);
#else
- flash_protect(FLAG_PROTECT_SET,
- CFG_ENV_ADDR,
- CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
- &flash_info[0]);
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif
#endif
Done:
- return size;
+ return size;
}
/*-----------------------------------------------------------------------
@@ -179,6 +209,11 @@ void flash_print_info (flash_info_t * info)
case (INTEL_ID_28F160F3T & FLASH_TYPEMASK):
printf ("28F160F3T (16Mbit)\n");
break;
+
+ case (INTEL_ID_28F160C3T & FLASH_TYPEMASK):
+ printf ("28F160C3T (16Mbit)\n");
+ break;
+
default:
printf ("Unknown Chip Type 0x%04x\n", i);
goto Done;
@@ -186,7 +221,7 @@ void flash_print_info (flash_info_t * info)
}
printf (" Size: %ld MB in %d Sectors\n",
- info->size >> 20, info->sector_count);
+ info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++) {
@@ -194,7 +229,7 @@ void flash_print_info (flash_info_t * info)
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
- info->protect[i] ? " (RO)" : " ");
+ info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
@@ -205,7 +240,7 @@ Done:
/*-----------------------------------------------------------------------
*/
-int flash_erase (flash_info_t *info, int s_first, int s_last)
+int flash_erase (flash_info_t * info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
@@ -229,33 +264,32 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
}
prot = 0;
- for (sect=s_first; sect<=s_last; ++sect) {
+ 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);
+ printf ("- Warning: %d protected sectors will not be erased!\n", prot);
} else {
printf ("\n");
}
start = get_timer (0);
- last = start;
+ last = start;
/* Start erase on unprotected sectors */
- for (sect = s_first; sect<=s_last; sect++) {
+ for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
- vu_long *addr = (vu_long *)(info->start[sect]);
+ vu_long *addr = (vu_long *) (info->start[sect]);
DEBUGF ("Erase sect %d @ 0x%08lX\n",
- sect, (ulong)addr);
+ sect, (ulong) addr);
/* Disable interrupts which might cause a timeout
* here.
*/
- flag = disable_interrupts();
+ flag = disable_interrupts ();
addr[0] = 0x00500050; /* clear status register */
addr[0] = 0x00200020; /* erase setup */
@@ -267,23 +301,23 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
/* re-enable interrupts if necessary */
if (flag)
- enable_interrupts();
+ enable_interrupts ();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while (((addr[0] & 0x00800080) != 0x00800080) ||
- ((addr[1] & 0x00800080) != 0x00800080) ) {
- if ((now=get_timer(start)) >
- CFG_FLASH_ERASE_TOUT) {
+ ((addr[1] & 0x00800080) != 0x00800080)) {
+ if ((now = get_timer (start)) >
+ CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
- addr[0] = 0x00B000B0; /* suspend erase */
- addr[0] = 0x00FF00FF; /* to read mode */
+ addr[0] = 0x00B000B0; /* suspend erase */
+ addr[0] = 0x00FF00FF; /* to read mode */
return 1;
}
/* show that we're waiting */
- if ((now - last) > 1000) { /* every second */
+ if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
@@ -306,7 +340,7 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
#define FLASH_WIDTH 8 /* flash bus width in bytes */
-int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong wp, cp, msr;
int l, rc, i;
@@ -315,16 +349,16 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
ulong *datal = &data[1];
DEBUGF ("Flash write_buff: @ 0x%08lx, src 0x%08lx len %ld\n",
- addr, (ulong)src, cnt);
+ addr, (ulong) src, cnt);
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
- msr = get_msr();
- set_msr(msr | MSR_FP);
+ msr = get_msr ();
+ set_msr (msr | MSR_FP);
- wp = (addr & ~(FLASH_WIDTH-1)); /* get lower aligned address */
+ wp = (addr & ~(FLASH_WIDTH - 1)); /* get lower aligned address */
/*
* handle unaligned start bytes
@@ -335,39 +369,35 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
for (i = 0, cp = wp; i < l; i++, cp++) {
if (i >= 4) {
*datah = (*datah << 8) |
- ((*datal & 0xFF000000) >> 24);
+ ((*datal & 0xFF000000) >> 24);
}
- *datal = (*datal << 8) | (*(uchar *)cp);
+ *datal = (*datal << 8) | (*(uchar *) cp);
}
for (; i < FLASH_WIDTH && cnt > 0; ++i) {
- char tmp;
-
- tmp = *src;
-
- src++;
+ char tmp = *src++;
if (i >= 4) {
*datah = (*datah << 8) |
- ((*datal & 0xFF000000) >> 24);
+ ((*datal & 0xFF000000) >> 24);
}
*datal = (*datal << 8) | tmp;
-
- --cnt; ++cp;
+ --cnt;
+ ++cp;
}
for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) {
if (i >= 4) {
*datah = (*datah << 8) |
- ((*datal & 0xFF000000) >> 24);
+ ((*datal & 0xFF000000) >> 24);
}
- *datal = (*datah << 8) | (*(uchar *)cp);
+ *datal = (*datah << 8) | (*(uchar *) cp);
}
- if ((rc = write_data(info, wp, data)) != 0) {
- set_msr(msr);
+ if ((rc = write_data (info, wp, data)) != 0) {
+ set_msr (msr);
return (rc);
}
@@ -378,19 +408,19 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
* handle FLASH_WIDTH aligned part
*/
while (cnt >= FLASH_WIDTH) {
- *datah = *(ulong *)src;
- *datal = *(ulong *)(src + 4);
- if ((rc = write_data(info, wp, data)) != 0) {
- set_msr(msr);
+ *datah = *(ulong *) src;
+ *datal = *(ulong *) (src + 4);
+ if ((rc = write_data (info, wp, data)) != 0) {
+ set_msr (msr);
return (rc);
}
- wp += FLASH_WIDTH;
+ wp += FLASH_WIDTH;
cnt -= FLASH_WIDTH;
src += FLASH_WIDTH;
}
if (cnt == 0) {
- set_msr(msr);
+ set_msr (msr);
return (0);
}
@@ -399,31 +429,28 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
*/
*datah = *datal = 0;
for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) {
- char tmp;
-
- tmp = *src;
-
- src++;
+ char tmp = *src++;
if (i >= 4) {
- *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+ *datah = (*datah << 8) | ((*datal & 0xFF000000) >>
+ 24);
}
*datal = (*datal << 8) | tmp;
-
--cnt;
}
for (; i < FLASH_WIDTH; ++i, ++cp) {
if (i >= 4) {
- *datah = (*datah << 8) | ((*datal & 0xFF000000) >> 24);
+ *datah = (*datah << 8) | ((*datal & 0xFF000000) >>
+ 24);
}
- *datal = (*datal << 8) | (*(uchar *)cp);
+ *datal = (*datal << 8) | (*(uchar *) cp);
}
- rc = write_data(info, wp, data);
- set_msr(msr);
+ rc = write_data (info, wp, data);
+ set_msr (msr);
return (rc);
}
@@ -434,32 +461,32 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
* 1 - write timeout
* 2 - Flash not erased
*/
-static int write_data (flash_info_t *info, ulong dest, ulong *data)
+static int write_data (flash_info_t * info, ulong dest, ulong * data)
{
- vu_long *addr = (vu_long *)dest;
+ vu_long *addr = (vu_long *) dest;
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if (((addr[0] & data[0]) != data[0]) ||
- ((addr[1] & data[1]) != data[1]) ) {
+ ((addr[1] & data[1]) != data[1])) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
- flag = disable_interrupts();
+ flag = disable_interrupts ();
- addr[0] = 0x00400040; /* write setup */
- write_via_fpu(addr, data);
+ addr[0] = 0x00400040; /* write setup */
+ write_via_fpu (addr, data);
/* re-enable interrupts if necessary */
if (flag)
- enable_interrupts();
+ enable_interrupts ();
start = get_timer (0);
while (((addr[0] & 0x00800080) != 0x00800080) ||
- ((addr[1] & 0x00800080) != 0x00800080) ) {
- if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ ((addr[1] & 0x00800080) != 0x00800080)) {
+ if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
addr[0] = 0x00FF00FF; /* restore read mode */
return (1);
}
@@ -472,22 +499,24 @@ static int write_data (flash_info_t *info, ulong dest, ulong *data)
/*-----------------------------------------------------------------------
*/
-static void write_via_fpu(vu_long *addr, ulong *data)
+static void write_via_fpu (vu_long * addr, ulong * data)
{
- __asm__ __volatile__ ("lfd 1, 0(%0)" : : "r" (data));
- __asm__ __volatile__ ("stfd 1, 0(%0)" : : "r" (addr));
+ __asm__ __volatile__ ("lfd 1, 0(%0)"::"r" (data));
+ __asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));
}
+
/*-----------------------------------------------------------------------
*/
-static __inline__ unsigned long get_msr(void)
+static __inline__ unsigned long get_msr (void)
{
- unsigned long msr;
+ unsigned long msr;
+
+ __asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
- __asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
- return msr;
+ return msr;
}
-static __inline__ void set_msr(unsigned long msr)
+static __inline__ void set_msr (unsigned long msr)
{
- __asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
+ __asm__ __volatile__ ("mtmsr %0"::"r" (msr));
}