/* Remap FLASH according to real size */
memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
+#ifdef CONFIG_FLASH_16BIT
+ memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V | BR_PS_16; /* 16 Bit data port */
+#else
memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+#endif
/* Re-do sizing to get full correct info */
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
if (size_b1) {
memctl->memc_or1 = CFG_OR_TIMING_FLASH | (-size_b1 & 0xFFFF8000);
+#ifdef CONFIG_FLASH_16BIT
+ memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
+ BR_MS_GPCM | BR_V | BR_PS_16;
+#else
memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
BR_MS_GPCM | BR_V;
+#endif
/* Re-do sizing to get full correct info */
size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
+#ifdef CONFIG_FLASH_16BIT
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+#else
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
+#endif
}
} else {
/* set sector offsets for top boot block type */
ulong base = (ulong)addr;
/* Write auto select command: read Manufacturer ID */
+#ifdef CONFIG_FLASH_16BIT
+ vu_short *s_addr = (vu_short*)addr;
+ s_addr[0x5555] = 0x00AA;
+ s_addr[0x2AAA] = 0x0055;
+ s_addr[0x5555] = 0x0090;
+ value = s_addr[0];
+ value = value|(value<<16);
+#else
addr[0x5555] = 0x00AA00AA;
addr[0x2AAA] = 0x00550055;
addr[0x5555] = 0x00900090;
-
value = addr[0];
+#endif
switch (value) {
case AMD_MANUFACT:
info->size = 0;
return (0); /* no or unknown flash */
}
-
+#ifdef CONFIG_FLASH_16BIT
+ value = s_addr[1];
+ value = value|(value<<16);
+#else
value = addr[1]; /* device ID */
+#endif
switch (value) {
case AMD_ID_LV400T:
case AMD_ID_LV800B:
info->flash_id += FLASH_AM800B;
+#ifdef CONFIG_FLASH_16BIT
info->sector_count = 19;
- info->size = 0x00200000;
- break; /* => 2 MB */
+ info->size = 0x00100000; /* => 1 MB */
+#else
+ info->sector_count = 19;
+ info->size = 0x00200000; /* => 2 MB */
+#endif
+ break;
case AMD_ID_LV160T:
info->flash_id += FLASH_AM160T;
case AMD_ID_LV160B:
info->flash_id += FLASH_AM160B;
+#ifdef CONFIG_FLASH_16BIT
info->sector_count = 35;
- info->size = 0x00400000;
- break; /* => 4 MB */
+ info->size = 0x00200000; /* => 2 MB */
+#else
+ info->sector_count = 35;
+ info->size = 0x00400000; /* => 4 MB */
+#endif
+
+ break;
#if 0 /* enable when device IDs are available */
case AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
/* set up sector start address table */
if (info->flash_id & FLASH_BTYPE) {
/* set sector offsets for bottom boot block type */
+#ifdef CONFIG_FLASH_16BIT
+
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+#else
info->start[0] = base + 0x00000000;
info->start[1] = base + 0x00008000;
info->start[2] = base + 0x0000C000;
info->start[3] = base + 0x00010000;
for (i = 4; i < info->sector_count; i++) {
info->start[i] = base + (i * 0x00020000) - 0x00060000;
+#endif
}
} else {
/* set sector offsets for top boot block type */
* (A7 .. A0) = 0x02
* D0 = 1 if protected
*/
+#ifdef CONFIG_FLASH_16BIT
+ s_addr = (volatile unsigned short *)(info->start[i]);
+ info->protect[i] = s_addr[2] & 1;
+#else
addr = (volatile unsigned long *)(info->start[i]);
info->protect[i] = addr[2] & 1;
+#endif
}
}
if (info->flash_id != FLASH_UNKNOWN) {
addr = (volatile unsigned long *)info->start[0];
+#ifdef CONFIG_FLASH_16BIT
+ *s_addr = 0x00F0; /* reset bank */
+#else
*addr = 0x00F000F0; /* reset bank */
- }
+#endif
+ }
return (info->size);
}
{
vu_long *addr = (vu_long*)(info->start[0]);
int flag, prot, sect;
- ulong type, start, now, last;
+ ulong start, now, last;
+#ifdef CONFIG_FLASH_16BIT
+ vu_short *s_addr = (vu_short*)addr;
+#endif
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
}
return;
}
-
+/*#ifndef CONFIG_FLASH_16BIT
+ ulong type;
type = (info->flash_id & FLASH_VENDMASK);
if ((type != FLASH_MAN_SST) && (type != FLASH_MAN_STM)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return;
}
-
+#endif*/
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
+#ifdef CONFIG_FLASH_16BIT
+ vu_short *s_sect_addr = (vu_short*)(info->start[sect]);
+#else
vu_long *sect_addr = (vu_long*)(info->start[sect]);
-
+#endif
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
+#ifdef CONFIG_FLASH_16BIT
+
+ /*printf("\ns_sect_addr=%x",s_sect_addr);*/
+ s_addr[0x5555] = 0x00AA;
+ s_addr[0x2AAA] = 0x0055;
+ s_addr[0x5555] = 0x0080;
+ s_addr[0x5555] = 0x00AA;
+ s_addr[0x2AAA] = 0x0055;
+ s_sect_addr[0] = 0x0030;
+#else
addr[0x5555] = 0x00AA00AA;
addr[0x2AAA] = 0x00550055;
addr[0x5555] = 0x00800080;
addr[0x5555] = 0x00AA00AA;
addr[0x2AAA] = 0x00550055;
sect_addr[0] = 0x00300030;
-
+#endif
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
+#ifdef CONFIG_FLASH_16BIT
+ while ((s_sect_addr[0] & 0x0080) != 0x0080) {
+#else
while ((sect_addr[0] & 0x00800080) != 0x00800080) {
+#endif
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
return;
/* reset to read mode */
addr = (volatile unsigned long *)info->start[0];
+#ifdef CONFIG_FLASH_16BIT
+ s_addr[0] = 0x00F0; /* reset bank */
+#else
addr[0] = 0x00F000F0; /* reset bank */
+#endif
printf (" done\n");
}
static int write_word (flash_info_t *info, ulong dest, ulong data)
{
vu_long *addr = (vu_long*)(info->start[0]);
+
+#ifdef CONFIG_FLASH_16BIT
+ vu_short high_data;
+ vu_short low_data;
+ vu_short *s_addr = (vu_short*)addr;
+#endif
ulong start;
int flag;
if ((*((vu_long *)dest) & data) != data) {
return (2);
}
+
+#ifdef CONFIG_FLASH_16BIT
+ /* Write the 16 higher-bits */
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ high_data = ((data>>16) & 0x0000ffff);
+
+ s_addr[0x5555] = 0x00AA;
+ s_addr[0x2AAA] = 0x0055;
+ s_addr[0x5555] = 0x00A0;
+
+ *((vu_short *)dest) = high_data;
+
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((*((vu_short *)dest) & 0x0080) != (high_data & 0x0080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+
+
+ /* Write the 16 lower-bits */
+#endif
+
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
+#ifdef CONFIG_FLASH_16BIT
+ dest += 0x2;
+ low_data = (data & 0x0000ffff);
+ s_addr[0x5555] = 0x00AA;
+ s_addr[0x2AAA] = 0x0055;
+ s_addr[0x5555] = 0x00A0;
+ *((vu_short *)dest) = low_data;
+
+#else
addr[0x5555] = 0x00AA00AA;
addr[0x2AAA] = 0x00550055;
addr[0x5555] = 0x00A000A0;
-
*((vu_long *)dest) = data;
+#endif
/* re-enable interrupts if necessary */
if (flag)
/* data polling for D7 */
start = get_timer (0);
+
+#ifdef CONFIG_FLASH_16BIT
+ while ((*((vu_short *)dest) & 0x0080) != (low_data & 0x0080)) {
+#else
while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+#endif
+
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
#endif /* XXX */
/*
- * BR6/OR6: PUMA: SMA Bus 8 Bit
- * BR6: 0x10200401 OR6: 0xffe00182
+ * BR5/OR5: PUMA: SMA Bus 8 Bit
+ * BR5: 0x10200401 OR5: 0xffe00182
*/
#define PUMA_SMA8_BASE 0x10200000 /* PUMA SMA Bus 8 Bit */
#define PUMA_SMA8_OR_AM 0xFFE00000 /* 2 MB */
#define PUMA_SMA8_TIMING (OR_BI | OR_SCY_8_CLK | OR_EHTR)
#if PCU_E_WITH_SWAPPED_CS /* XXX */
-#define CFG_BR1_PRELIM ((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
-#define CFG_OR1_PRELIM (PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING)
+#define CFG_BR2_PRELIM ((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
+#define CFG_OR2_PRELIM (PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING)
#else /* XXX */
-#define CFG_BR6_PRELIM ((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
-#define CFG_OR6_PRELIM (PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING)
+#define CFG_BR5_PRELIM ((PUMA_SMA8_BASE & BR_BA_MSK) | BR_PS_8 | BR_V)
+#define CFG_OR5_PRELIM (PUMA_SMA8_OR_AM | PUMA_SMA8_TIMING)
#endif /* XXX */
/*
- * BR5/OR5: PUMA: SMA Bus 16 Bit
- * BR5: 0x10600801 OR5: 0xffe00182
+ * BR6/OR6: PUMA: SMA Bus 16 Bit
+ * BR6: 0x10600801 OR6: 0xffe00182
*/
#define PUMA_SMA16_BASE 0x10600000 /* PUMA SMA Bus 16 Bit */
#define PUMA_SMA16_OR_AM 0xFFE00000 /* 2 MB */
#define PUMA_SMA16_TIMING (OR_BI | OR_SCY_8_CLK | OR_EHTR)
#if PCU_E_WITH_SWAPPED_CS /* XXX */
-#define CFG_BR2_PRELIM ((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
-#define CFG_OR2_PRELIM (PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING)
+#define CFG_BR1_PRELIM ((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR1_PRELIM (PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING)
#else /* XXX */
-#define CFG_BR5_PRELIM ((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
-#define CFG_OR5_PRELIM (PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING)
+#define CFG_BR6_PRELIM ((PUMA_SMA16_BASE & BR_BA_MSK) | BR_PS_16 | BR_V)
+#define CFG_OR6_PRELIM (PUMA_SMA16_OR_AM | PUMA_SMA16_TIMING)
#endif /* XXX */
/*