summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2010-11-27 00:55:51 +0800
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2010-12-03 01:53:14 +0800
commit998549869511593d94b0ca8ac7222a35197d3076 (patch)
tree4dfe68413de1082b0d2e43fc9da856b887670bc0
parent0df2a8d2632715b3fa4d27a632c2527d99904180 (diff)
downloadbarebox-998549869511593d94b0ca8ac7222a35197d3076.tar.gz
barebox-998549869511593d94b0ca8ac7222a35197d3076.tar.xz
cfi_flash: introduce flash cmdset fixup
Move fixing up like geometry reversal into separate functions. The geometry reversal fixup is now performed by altering the qry structure directly, which makes the sector init code slightly cleaner. based on U-Boot Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
-rw-r--r--drivers/nor/cfi_flash.c43
-rw-r--r--drivers/nor/cfi_flash.h1
-rw-r--r--drivers/nor/cfi_flash_amd.c35
-rw-r--r--drivers/nor/cfi_flash_intel.c12
4 files changed, 52 insertions, 39 deletions
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 6d22a531b4..2fa2c6b900 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -314,7 +314,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
uchar num_erase_regions;
int erase_region_size;
int erase_region_count;
- int geometry_reversed = 0;
int cur_offset = 0;
struct cfi_qry qry;
@@ -368,38 +367,7 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
info->cfi_cmd_set->flash_read_jedec_ids (info);
flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
- switch (info->vendor) {
- case CFI_CMDSET_INTEL_STANDARD:
- case CFI_CMDSET_INTEL_EXTENDED:
- default:
-#ifdef CFG_FLASH_PROTECTION
- /* read legacy lock/unlock bit from intel flash */
- if (info->ext_addr) {
- info->legacy_unlock = flash_read_uchar (info,
- info->ext_addr + 5) & 0x08;
- }
-#endif
- break;
- case CFI_CMDSET_AMD_STANDARD:
- case CFI_CMDSET_AMD_EXTENDED:
- /* check if flash geometry needs reversal */
- if (num_erase_regions <= 1)
- break;
- /* 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) {
- geometry_reversed = 1;
- }
- break;
- }
- /* CFI >= 1.1, deduct from top/bottom flag */
- /* note: ext_addr is valid since cfi_version > 0 */
- if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
- geometry_reversed = 1;
- }
- break;
- }
+ info->cfi_cmd_set->flash_fixup (info, &qry);
debug ("manufacturer is %d\n", info->vendor);
debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
@@ -423,7 +391,6 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
sector = base;
for (i = 0; i < num_erase_regions; i++) {
- unsigned int __region = i;
struct mtd_erase_region_info *region = &info->eraseregions[i];
if (i > NUM_ERASE_REGIONS) {
@@ -431,11 +398,9 @@ static ulong flash_get_size (struct flash_info *info, ulong base)
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
- if (geometry_reversed)
- __region = num_erase_regions - 1 - i;
-
- tmp = le32_to_cpu(qry.erase_region_info[__region]);
- debug("erase region %u: 0x%08lx\n", __region, tmp);
+
+ tmp = le32_to_cpu(qry.erase_region_info[i]);
+ debug("erase region %u: 0x%08lx\n", i, tmp);
erase_region_count = (tmp & 0xffff) + 1;
tmp >>= 16;
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index bbeb377219..f9023dcafa 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -114,6 +114,7 @@ struct cfi_cmd_set {
void (*flash_prepare_write) (struct flash_info *info);
int (*flash_status_check) (struct flash_info *info, flash_sect_t sector, uint64_t tout, char *prompt);
int (*flash_real_protect) (struct flash_info *info, long sector, int prot);
+ void (*flash_fixup) (struct flash_info *info, struct cfi_qry *qry);
};
extern struct cfi_cmd_set cfi_cmd_set_intel;
diff --git a/drivers/nor/cfi_flash_amd.c b/drivers/nor/cfi_flash_amd.c
index f2257571fa..b50de221f8 100644
--- a/drivers/nor/cfi_flash_amd.c
+++ b/drivers/nor/cfi_flash_amd.c
@@ -2,6 +2,23 @@
#include <stdio.h>
#include "cfi_flash.h"
+/*-----------------------------------------------------------------------
+ * Reverse the order of the erase regions in the CFI QRY structure.
+ * This is needed for chips that are either a) correctly detected as
+ * top-boot, or b) buggy.
+ */
+static void cfi_reverse_geometry(struct cfi_qry *qry)
+{
+ unsigned int i, j;
+ u32 tmp;
+
+ for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
+ tmp = qry->erase_region_info[i];
+ qry->erase_region_info[i] = qry->erase_region_info[j];
+ qry->erase_region_info[j] = tmp;
+ }
+}
+
static void flash_unlock_seq (struct flash_info *info)
{
flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_UNLOCK_START);
@@ -184,6 +201,23 @@ static int amd_flash_real_protect (struct flash_info *info, long sector, int pro
return 0;
}
+static void amd_flash_fixup (struct flash_info *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);
+ }
+ }
+}
+
struct cfi_cmd_set cfi_cmd_set_amd = {
.flash_write_cfibuffer = amd_flash_write_cfibuffer,
.flash_erase_one = amd_flash_erase_one,
@@ -192,5 +226,6 @@ struct cfi_cmd_set cfi_cmd_set_amd = {
.flash_prepare_write = amd_flash_prepare_write,
.flash_status_check = flash_generic_status_check,
.flash_real_protect = amd_flash_real_protect,
+ .flash_fixup = amd_flash_fixup,
};
diff --git a/drivers/nor/cfi_flash_intel.c b/drivers/nor/cfi_flash_intel.c
index 8e8a820600..c3cbad55f9 100644
--- a/drivers/nor/cfi_flash_intel.c
+++ b/drivers/nor/cfi_flash_intel.c
@@ -141,6 +141,17 @@ static int intel_flash_real_protect (struct flash_info *info, long sector, int p
return 0;
}
+static void intel_flash_fixup (struct flash_info *info, struct cfi_qry *qry)
+{
+#ifdef CFG_FLASH_PROTECTION
+ /* read legacy lock/unlock bit from intel flash */
+ if (info->ext_addr) {
+ info->legacy_unlock = flash_read_uchar (info,
+ info->ext_addr + 5) & 0x08;
+ }
+#endif
+}
+
struct cfi_cmd_set cfi_cmd_set_intel = {
.flash_write_cfibuffer = intel_flash_write_cfibuffer,
.flash_erase_one = intel_flash_erase_one,
@@ -149,5 +160,6 @@ struct cfi_cmd_set cfi_cmd_set_intel = {
.flash_prepare_write = intel_flash_prepare_write,
.flash_status_check = intel_flash_status_check,
.flash_real_protect = intel_flash_real_protect,
+ .flash_fixup = intel_flash_fixup,
};