|
@@ -1383,20 +1383,6 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
|
|
cmdset_amd_read_jedec_ids(info);
|
|
cmdset_amd_read_jedec_ids(info);
|
|
flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
|
|
flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
|
|
|
|
|
|
- /* check if flash geometry needs reversal */
|
|
|
|
- if (qry->num_erase_regions > 1) {
|
|
|
|
- /* reverse geometry if top boot part */
|
|
|
|
- if (info->cfi_version < 0x3131) {
|
|
|
|
- /* CFI < 1.1, try to guess from device id */
|
|
|
|
- if ((info->device_id & 0x80) != 0)
|
|
|
|
- cfi_reverse_geometry(qry);
|
|
|
|
- } else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
|
|
|
|
- /* CFI >= 1.1, deduct from top/bottom flag */
|
|
|
|
- /* note: ext_addr is valid since cfi_version > 0 */
|
|
|
|
- cfi_reverse_geometry(qry);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1567,6 +1553,49 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Manufacturer-specific quirks. Add workarounds for geometry
|
|
|
|
+ * reversal, etc. here.
|
|
|
|
+ */
|
|
|
|
+static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)
|
|
|
|
+{
|
|
|
|
+ /* check if flash geometry needs reversal */
|
|
|
|
+ if (qry->num_erase_regions > 1) {
|
|
|
|
+ /* reverse geometry if top boot part */
|
|
|
|
+ if (info->cfi_version < 0x3131) {
|
|
|
|
+ /* CFI < 1.1, try to guess from device id */
|
|
|
|
+ if ((info->device_id & 0x80) != 0)
|
|
|
|
+ cfi_reverse_geometry(qry);
|
|
|
|
+ } else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
|
|
|
|
+ /* CFI >= 1.1, deduct from top/bottom flag */
|
|
|
|
+ /* note: ext_addr is valid since cfi_version > 0 */
|
|
|
|
+ cfi_reverse_geometry(qry);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
|
|
|
|
+{
|
|
|
|
+ int reverse_geometry = 0;
|
|
|
|
+
|
|
|
|
+ /* Check the "top boot" bit in the PRI */
|
|
|
|
+ if (info->ext_addr && !(flash_read_uchar(info, info->ext_addr + 6) & 1))
|
|
|
|
+ reverse_geometry = 1;
|
|
|
|
+
|
|
|
|
+ /* AT49BV6416(T) list the erase regions in the wrong order.
|
|
|
|
+ * However, the device ID is identical with the non-broken
|
|
|
|
+ * AT49BV642D since u-boot only reads the low byte (they
|
|
|
|
+ * differ in the high byte.) So leave out this fixup for now.
|
|
|
|
+ */
|
|
|
|
+#if 0
|
|
|
|
+ if (info->device_id == 0xd6 || info->device_id == 0xd2)
|
|
|
|
+ reverse_geometry = !reverse_geometry;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (reverse_geometry)
|
|
|
|
+ cfi_reverse_geometry(qry);
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* The following code cannot be run from FLASH!
|
|
* The following code cannot be run from FLASH!
|
|
*
|
|
*
|
|
@@ -1629,6 +1658,16 @@ ulong flash_get_size (ulong base, int banknum)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Do manufacturer-specific fixups */
|
|
|
|
+ switch (info->manufacturer_id) {
|
|
|
|
+ case 0x0001:
|
|
|
|
+ flash_fixup_amd(info, &qry);
|
|
|
|
+ break;
|
|
|
|
+ case 0x001f:
|
|
|
|
+ flash_fixup_atmel(info, &qry);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
debug ("manufacturer is %d\n", info->vendor);
|
|
debug ("manufacturer is %d\n", info->vendor);
|
|
debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
|
|
debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
|
|
debug ("device id is 0x%x\n", info->device_id);
|
|
debug ("device id is 0x%x\n", info->device_id);
|