X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fcfi_flash.c;h=a389cd101c2f55e62ca8ab90efaf395234d98713;hb=968294bd7b9b540f53c1fb3c809da464623a4362;hp=60dbb7864f2b40476e7dab9a03930aa89dc50158;hpb=1199c377cf14c240b903e351ab02b3b2cd3800c6;p=u-boot diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 60dbb7864f..a389cd101c 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -11,24 +11,7 @@ * Copyright (C) 2006 * Tolunay Orkun * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * + * SPDX-License-Identifier: GPL-2.0+ */ /* The DEBUG define must be before common to enable debugging */ @@ -38,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -183,16 +167,16 @@ u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64"))); flash_info_t *flash_get_info(ulong base) { int i; - flash_info_t *info = NULL; + flash_info_t *info; for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { - info = & flash_info[i]; + info = &flash_info[i]; if (info->size && info->start[0] <= base && base <= info->start[0] + info->size - 1) - break; + return info; } - return info; + return NULL; } #endif @@ -1640,9 +1624,10 @@ static void cfi_reverse_geometry(struct cfi_qry *qry) 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; + tmp = get_unaligned(&(qry->erase_region_info[i])); + put_unaligned(get_unaligned(&(qry->erase_region_info[j])), + &(qry->erase_region_info[i])); + put_unaligned(tmp, &(qry->erase_region_info[j])); } } @@ -1795,7 +1780,7 @@ static int flash_detect_legacy(phys_addr_t base, int banknum) }; int i; - for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { + for (i = 0; i < ARRAY_SIZE(modes); i++) { info->vendor = modes[i]; info->start[0] = (ulong)map_physmem(base, @@ -1818,7 +1803,7 @@ static int flash_detect_legacy(phys_addr_t base, int banknum) break; else unmap_physmem((void *)info->start[0], - MAP_NOCACHE); + info->portwidth); } } @@ -1881,8 +1866,7 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry) /* Issue FLASH reset command */ flash_cmd_reset(info); - for (cfi_offset=0; - cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint); + for (cfi_offset = 0; cfi_offset < ARRAY_SIZE(flash_offset_cfi); cfi_offset++) { flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI); @@ -2024,6 +2008,26 @@ static void flash_fixup_sst(flash_info_t *info, struct cfi_qry *qry) } } +static void flash_fixup_num(flash_info_t *info, struct cfi_qry *qry) +{ + /* + * The M29EW devices seem to report the CFI information wrong + * when it's in 8 bit mode. + * There's an app note from Numonyx on this issue. + * So adjust the buffer size for M29EW while operating in 8-bit mode + */ + if (((qry->max_buf_write_size) > 0x8) && + (info->device_id == 0x7E) && + (info->device_id2 == 0x2201 || + info->device_id2 == 0x2301 || + info->device_id2 == 0x2801 || + info->device_id2 == 0x4801)) { + debug("Adjusted buffer size on Numonyx flash" + " M29EW family in 8 bit mode\n"); + qry->max_buf_write_size = 0x8; + } +} + /* * The following code cannot be run from FLASH! * @@ -2053,8 +2057,8 @@ ulong flash_get_size (phys_addr_t base, int banknum) info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE); if (flash_detect_cfi (info, &qry)) { - info->vendor = le16_to_cpu(qry.p_id); - info->ext_addr = le16_to_cpu(qry.p_adr); + info->vendor = le16_to_cpu(get_unaligned(&(qry.p_id))); + info->ext_addr = le16_to_cpu(get_unaligned(&(qry.p_adr))); num_erase_regions = qry.num_erase_regions; if (info->ext_addr) { @@ -2105,6 +2109,9 @@ ulong flash_get_size (phys_addr_t base, int banknum) case 0x00bf: /* SST */ flash_fixup_sst(info, &qry); break; + case 0x0089: /* Numonyx */ + flash_fixup_num(info, &qry); + break; } debug ("manufacturer is %d\n", info->vendor); @@ -2140,7 +2147,8 @@ ulong flash_get_size (phys_addr_t base, int banknum) break; } - tmp = le32_to_cpu(qry.erase_region_info[i]); + tmp = le32_to_cpu(get_unaligned( + &(qry.erase_region_info[i]))); debug("erase region %u: 0x%08lx\n", i, tmp); erase_region_count = (tmp & 0xffff) + 1; @@ -2310,7 +2318,7 @@ void flash_protect_default(void) #endif #if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST) - for (i = 0; i < (sizeof(apl) / sizeof(struct apl_s)); i++) { + for (i = 0; i < ARRAY_SIZE(apl); i++) { debug("autoprotecting from %08lx to %08lx\n", apl[i].start, apl[i].start + apl[i].size - 1); flash_protect(FLAG_PROTECT_SET,