/*----------------------------------------------------------------------- */ void flash_reset (void) { if (flash_info[0].flash_id != FLASH_UNKNOWN) { V_ULONG (flash_info[0].start[0]) = 0x00F000F0; V_ULONG (flash_info[0].start[0] + 4) = 0x00F000F0; } }
/*----------------------------------------------------------------------- */ ulong flash_get_size (ulong baseaddr, flash_info_t * info) { short i; unsigned long flashtest_h, flashtest_l; /* Write auto select command sequence and test FLASH answer */ V_ULONG (baseaddr + ((ulong) 0x0555 << 3)) = 0x00AA00AA; V_ULONG (baseaddr + ((ulong) 0x02AA << 3)) = 0x00550055; V_ULONG (baseaddr + ((ulong) 0x0555 << 3)) = 0x00900090; V_ULONG (baseaddr + 4 + ((ulong) 0x0555 << 3)) = 0x00AA00AA; V_ULONG (baseaddr + 4 + ((ulong) 0x02AA << 3)) = 0x00550055; V_ULONG (baseaddr + 4 + ((ulong) 0x0555 << 3)) = 0x00900090; flashtest_h = V_ULONG (baseaddr); /* manufacturer ID */ flashtest_l = V_ULONG (baseaddr + 4); switch ((int) flashtest_h) { case AMD_MANUFACT: info->flash_id = FLASH_MAN_AMD; break; case FUJ_MANUFACT: info->flash_id = FLASH_MAN_FUJ; break; default: info->flash_id = FLASH_UNKNOWN; info->sector_count = 0; info->size = 0; return (0); /* no or unknown flash */ } flashtest_h = V_ULONG (baseaddr + 8); /* device ID */ flashtest_l = V_ULONG (baseaddr + 12); if (flashtest_h != flashtest_l) { info->flash_id = FLASH_UNKNOWN; } else { switch (flashtest_h) { case AMD_ID_LV800T: info->flash_id += FLASH_AM800T; info->sector_count = 19; info->size = 0x00400000; break; /* 4 * 1 MB = 4 MB */ case AMD_ID_LV800B: info->flash_id += FLASH_AM800B; info->sector_count = 19; info->size = 0x00400000; break; /* 4 * 1 MB = 4 MB */ case AMD_ID_LV160T: info->flash_id += FLASH_AM160T; info->sector_count = 35; info->size = 0x00800000; break; /* 4 * 2 MB = 8 MB */ case AMD_ID_LV160B: info->flash_id += FLASH_AM160B; info->sector_count = 35; info->size = 0x00800000; break; /* 4 * 2 MB = 8 MB */ case AMD_ID_DL322T: info->flash_id += FLASH_AMDL322T; info->sector_count = 71; info->size = 0x01000000; break; /* 4 * 4 MB = 16 MB */ case AMD_ID_DL322B: info->flash_id += FLASH_AMDL322B; info->sector_count = 71; info->size = 0x01000000; break; /* 4 * 4 MB = 16 MB */ case AMD_ID_DL323T: info->flash_id += FLASH_AMDL323T; info->sector_count = 71; info->size = 0x01000000; break; /* 4 * 4 MB = 16 MB */ case AMD_ID_DL323B: info->flash_id += FLASH_AMDL323B; info->sector_count = 71; info->size = 0x01000000; break; /* 4 * 4 MB = 16 MB */ case AMD_ID_LV640U: info->flash_id += FLASH_AM640U; info->sector_count = 128; info->size = 0x02000000; break; /* 4 * 8 MB = 32 MB */ default: info->flash_id = FLASH_UNKNOWN; return (0); /* no or unknown flash */ } } if (flashtest_h == AMD_ID_LV640U) { /* set up sector start adress table (uniform sector type) */ for (i = 0; i < info->sector_count; i++) info->start[i] = baseaddr + (i * 0x00040000); } else if (info->flash_id & FLASH_BTYPE) { /* set up sector start adress table (bottom sector type) */ info->start[0] = baseaddr + 0x00000000; info->start[1] = baseaddr + 0x00010000; info->start[2] = baseaddr + 0x00018000; info->start[3] = baseaddr + 0x00020000; for (i = 4; i < info->sector_count; i++) { info->start[i] = baseaddr + (i * 0x00040000) - 0x000C0000; } } else { /* set up sector start adress table (top sector type) */ i = info->sector_count - 1; info->start[i--] = baseaddr + info->size - 0x00010000; info->start[i--] = baseaddr + info->size - 0x00018000; info->start[i--] = baseaddr + info->size - 0x00020000; for (; i >= 0; i--) { info->start[i] = baseaddr + i * 0x00040000; } } /* check for protected sectors */ for (i = 0; i < info->sector_count; i++) { /* read sector protection at sector address, (A7 .. A0) = 0x02 */ if ((V_ULONG (info->start[i] + 16) & 0x00010001) || (V_ULONG (info->start[i] + 20) & 0x00010001)) { info->protect[i] = 1; /* D0 = 1 if protected */ } else { info->protect[i] = 0; } } flash_reset (); return (info->size); }
/*----------------------------------------------------------------------- */ ulong flash_get_size( ulong baseaddr, flash_info_t *info ) { short i; unsigned long flashtest_h, flashtest_l; /* Write auto select command sequence and test FLASH answer */ V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00AA00AA; V_ULONG(baseaddr + ((ulong)0x02AA << 3)) = 0x00550055; V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00900090; V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00AA00AA; V_ULONG(baseaddr + 4 + ((ulong)0x02AA << 3)) = 0x00550055; V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00900090; flashtest_h = V_ULONG(baseaddr); /* manufacturer ID */ flashtest_l = V_ULONG(baseaddr + 4); if ((int)flashtest_h == AMD_MANUFACT) { info->flash_id = FLASH_MAN_AMD; } else { info->flash_id = FLASH_UNKNOWN; info->sector_count = 0; info->size = 0; return (0); /* no or unknown flash */ } flashtest_h = V_ULONG(baseaddr + 8); /* device ID */ flashtest_l = V_ULONG(baseaddr + 12); if (flashtest_h != flashtest_l) { info->flash_id = FLASH_UNKNOWN; return(0); } switch((int)flashtest_h) { case AMD_ID_DL323B: info->flash_id += FLASH_AMDL323B; info->sector_count = 71; info->size = 0x01000000; /* 4 * 4 MB = 16 MB */ break; case AMD_ID_LV640U: /* AMDLV640 and AMDLV641 have same ID */ info->flash_id += FLASH_AMLV640U; info->sector_count = 128; info->size = 0x02000000; /* 4 * 8 MB = 32 MB */ break; default: info->flash_id = FLASH_UNKNOWN; return(0); /* no or unknown flash */ } if(flashtest_h == AMD_ID_LV640U) { /* set up sector start adress table (uniform sector type) */ for (i = 0; i < info->sector_count; i++) info->start[i] = baseaddr + (i * 0x00040000); } else { /* set up sector start adress table (bottom sector type) */ for (i = 0; i < 8; i++) { info->start[i] = baseaddr + (i * 0x00008000); } for (i = 8; i < info->sector_count; i++) { info->start[i] = baseaddr + (i * 0x00040000) - 0x001C0000; } } /* check for protected sectors */ for (i = 0; i < info->sector_count; i++) { /* read sector protection at sector address, (A7 .. A0) = 0x02 */ if ((V_ULONG( info->start[i] + 16 ) & 0x00010001) || (V_ULONG( info->start[i] + 20 ) & 0x00010001)) { info->protect[i] = 1; /* D0 = 1 if protected */ } else { info->protect[i] = 0; } } flash_reset(); return(info->size); }