* [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3
@ 2007-12-13 11:56 Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 1/7] cfi_flash: Break long lines Haavard Skinnemoen
2007-12-13 12:56 ` [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Stefan Roese
0 siblings, 2 replies; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
This is a resend of the whole series rebased onto the latest head of
the CFI tree.
Patch #3 is not actually present since it's too large to fit under the
40K limit. I've put it on a web server instead:
http://avr32linux.org/twiki/pub/Sandbox/UbootCfiCleanup/0003-cfi_flash-Reorder-functions-and-eliminate-extra-pro.patch
I did a quick test on one of my avr32 boards and while it identified
the flash just fine, it couldn't erase it. I think the flash chip
needs to be unprotected, and the current code doesn't do this (it's
kind of a quirk with the particular Atmel chip I'm using, AT49BV6416.)
I'm planning to rework the code dealing with chip-specific quirks
later on and add code to smack this chip on the head as needed. It
also has a geometry reversal issue which is not detected properly by
the current code (I think there's a reason this chip was quickly
replaced by AT49BV642D, which doesn't have any of these problems.)
Haavard Skinnemoen (7):
cfi_flash: Break long lines
cfi_flash: Make some needlessly global functions static
cfi_flash: Reorder functions and eliminate extra prototypes
Implement __raw_{read,write}[bwl] on all architectures
cfi_flash: Introduce read and write accessors
Introduce map_physmem() and unmap_physmem()
cfi_flash: Use map_physmem() and unmap_physmem()
drivers/mtd/cfi_flash.c | 1699 +++++++++++++++++++++++--------------------
include/asm-arm/io.h | 26 +
include/asm-avr32/io.h | 32 +
include/asm-blackfin/io.h | 26 +
include/asm-i386/io.h | 26 +
include/asm-m68k/io.h | 41 +
include/asm-microblaze/io.h | 26 +
include/asm-mips/io.h | 26 +
include/asm-nios/io.h | 34 +
include/asm-nios2/io.h | 34 +
include/asm-ppc/io.h | 58 ++-
11 files changed, 1249 insertions(+), 779 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 1/7] cfi_flash: Break long lines
2007-12-13 11:56 [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 2/7] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
2007-12-13 12:56 ` [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Stefan Roese
1 sibling, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
This patch tries to keep all lines in the cfi_flash driver below 80
columns. There are a few lines left which don't fit this requirement
because I couldn't find any trivial way to break them (i.e. it would
take some restructuring, which I intend to do in a later patch.)
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mtd/cfi_flash.c | 304 +++++++++++++++++++++++++++++------------------
1 files changed, 189 insertions(+), 115 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index c3293d0..c73b74a 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -42,9 +42,12 @@
#ifdef CFG_FLASH_CFI_DRIVER
/*
- * This file implements a Common Flash Interface (CFI) driver for U-Boot.
- * The width of the port and the width of the chips are determined at initialization.
- * These widths are used to calculate the address for access CFI data structures.
+ * This file implements a Common Flash Interface (CFI) driver for
+ * U-Boot.
+ *
+ * The width of the port and the width of the chips are determined at
+ * initialization. These widths are used to calculate the address for
+ * access CFI data structures.
*
* References
* JEDEC Standard JESD68 - Common Flash Interface (CFI)
@@ -55,7 +58,7 @@
* AMD/Spansion Application Note: Migration from Single-byte to Three-byte
* Device IDs, Publication Number 25538 Revision A, November 8, 2001
*
- * define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
+ * Define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
* reading and writing ... (yes there is such a Hardware).
*/
@@ -106,7 +109,8 @@
#define FLASH_OFFSET_CFI_ALT 0x555
#define FLASH_OFFSET_CFI_RESP 0x10
#define FLASH_OFFSET_PRIMARY_VENDOR 0x13
-#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15 /* extended query table primary addr */
+/* extended query table primary address */
+#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15
#define FLASH_OFFSET_WTOUT 0x1F
#define FLASH_OFFSET_WBTOUT 0x20
#define FLASH_OFFSET_ETOUT 0x21
@@ -154,7 +158,7 @@ typedef union {
#define NUM_ERASE_REGIONS 4 /* max. number of erase regions */
-static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
+static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
/* use CFG_MAX_FLASH_BANKS_DETECT if defined */
#ifdef CFG_MAX_FLASH_BANKS_DETECT
@@ -181,14 +185,19 @@ typedef unsigned long flash_sect_t;
static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd);
static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_isequal (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd);
+static int flash_isset (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd);
+static int flash_toggle (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd);
static void flash_read_jedec_ids (flash_info_t * info);
static int flash_detect_cfi (flash_info_t * info);
-static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
+static int flash_write_cfiword (flash_info_t * info, ulong dest,
+ cfiword_t cword);
static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
ulong tout, char *prompt);
ulong flash_get_size (ulong base, int banknum);
@@ -196,13 +205,15 @@ ulong flash_get_size (ulong base, int banknum);
static flash_info_t *flash_get_info(ulong base);
#endif
#ifdef CFG_FLASH_USE_BUFFER_WRITE
-static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
+static int flash_write_cfibuffer (flash_info_t * info, ulong dest,
+ uchar * cp, int len);
#endif
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
-inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
+inline uchar *
+flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
{
return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
}
@@ -316,7 +327,8 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
#endif
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
- (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
+ (addr[(2 * info->portwidth)]) |
+ (addr[(3 * info->portwidth)] << 8);
#else
retval = (addr[(2 * info->portwidth) - 1] << 24) |
(addr[(info->portwidth) - 1] << 16) |
@@ -336,17 +348,22 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
int flash_detect_legacy(ulong base, int banknum)
{
flash_info_t *info = &flash_info[banknum];
+
if (board_flash_get_legacy(base, banknum, info)) {
/* board code may have filled info completely. If not, we
use JEDEC ID probing. */
if (!info->vendor) {
- int modes[] = { CFI_CMDSET_AMD_STANDARD, CFI_CMDSET_INTEL_STANDARD };
+ int modes[] = {
+ CFI_CMDSET_AMD_STANDARD,
+ CFI_CMDSET_INTEL_STANDARD
+ };
int i;
- for(i=0; i<sizeof(modes)/sizeof(modes[0]); i++) {
+ for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
info->vendor = modes[i];
info->start[0] = base;
- if (info->portwidth == FLASH_CFI_8BIT && info->interface == FLASH_CFI_X8X16) {
+ if (info->portwidth == FLASH_CFI_8BIT
+ && info->interface == FLASH_CFI_X8X16) {
info->addr_unlock1 = 0x2AAA;
info->addr_unlock2 = 0x5555;
} else {
@@ -354,11 +371,15 @@ int flash_detect_legacy(ulong base, int banknum)
info->addr_unlock2 = 0x2AAA;
}
flash_read_jedec_ids(info);
- debug("JEDEC PROBE: ID %x %x %x\n", info->manufacturer_id, info->device_id, info->device_id2);
+ debug("JEDEC PROBE: ID %x %x %x\n",
+ info->manufacturer_id,
+ info->device_id,
+ info->device_id2);
if (jedec_flash_match(info, base))
break;
}
}
+
switch(info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
@@ -403,38 +424,45 @@ unsigned long flash_init (void)
size += flash_info[i].size;
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
#ifndef CFG_FLASH_QUIET_TEST
- printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
- i+1, flash_info[i].size, flash_info[i].size << 20);
+ printf ("## Unknown FLASH on Bank %d "
+ "- Size = 0x%08lx = %ld MB\n",
+ i+1, flash_info[i].size,
+ flash_info[i].size << 20);
#endif /* CFG_FLASH_QUIET_TEST */
}
#ifdef CFG_FLASH_PROTECTION
else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
/*
- * Only the U-Boot image and it's environment is protected,
- * all other sectors are unprotected (unlocked) if flash
- * hardware protection is used (CFG_FLASH_PROTECTION) and
- * the environment variable "unlock" is set to "yes".
+ * Only the U-Boot image and it's environment
+ * is protected, all other sectors are
+ * unprotected (unlocked) if flash hardware
+ * protection is used (CFG_FLASH_PROTECTION)
+ * and the environment variable "unlock" is
+ * set to "yes".
*/
if (flash_info[i].legacy_unlock) {
int k;
/*
- * Disable legacy_unlock temporarily, since
- * flash_real_protect would relock all other sectors
- * again otherwise.
+ * Disable legacy_unlock temporarily,
+ * since flash_real_protect would
+ * relock all other sectors again
+ * otherwise.
*/
flash_info[i].legacy_unlock = 0;
/*
- * Legacy unlocking (e.g. Intel J3) -> unlock only one
- * sector. This will unlock all sectors.
+ * Legacy unlocking (e.g. Intel J3) ->
+ * unlock only one sector. This will
+ * unlock all sectors.
*/
flash_real_protect (&flash_info[i], 0, 0);
flash_info[i].legacy_unlock = 1;
/*
- * Manually mark other sectors as unlocked (unprotected)
+ * Manually mark other sectors as
+ * unlocked (unprotected)
*/
for (k = 1; k < flash_info[i].sector_count; k++)
flash_info[i].protect[k] = 0;
@@ -444,7 +472,8 @@ unsigned long flash_init (void)
*/
flash_protect (FLAG_PROTECT_CLEAR,
flash_info[i].start[0],
- flash_info[i].start[0] + flash_info[i].size - 1,
+ flash_info[i].start[0]
+ + flash_info[i].size - 1,
&flash_info[i]);
}
}
@@ -485,7 +514,7 @@ static flash_info_t *flash_get_info(ulong base)
int i;
flash_info_t * info = 0;
- for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
info = & flash_info[i];
if (info->size && info->start[0] <= base &&
base <= info->start[0] + info->size - 1)
@@ -520,7 +549,8 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
}
}
if (prot) {
- printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
} else {
putc ('\n');
}
@@ -531,23 +561,31 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
- flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
- flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
- flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
+ flash_write_cmd (info, sect, 0,
+ FLASH_CMD_CLEAR_STATUS);
+ flash_write_cmd (info, sect, 0,
+ FLASH_CMD_BLOCK_ERASE);
+ flash_write_cmd (info, sect, 0,
+ FLASH_CMD_ERASE_CONFIRM);
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
flash_unlock_seq (info, sect);
- flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_ERASE_START);
+ flash_write_cmd (info, sect,
+ info->addr_unlock1,
+ AMD_CMD_ERASE_START);
flash_unlock_seq (info, sect);
- flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
+ flash_write_cmd (info, sect, 0,
+ AMD_CMD_ERASE_SECTOR);
break;
#ifdef CONFIG_FLASH_CFI_LEGACY
case CFI_CMDSET_AMD_LEGACY:
flash_unlock_seq (info, 0);
- flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_ERASE_START);
+ flash_write_cmd (info, 0, info->addr_unlock1,
+ AMD_CMD_ERASE_START);
flash_unlock_seq (info, 0);
- flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
+ flash_write_cmd (info, sect, 0,
+ AMD_CMD_ERASE_SECTOR);
break;
#endif
default:
@@ -585,8 +623,8 @@ void flash_print_info (flash_info_t * info)
printf (" Size: %ld kB in %d Sectors\n",
info->size >> 10, info->sector_count);
else
- printf (" Size: %ld MB in %d Sectors\n",
- info->size >> 20, info->sector_count);
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
printf (" ");
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
@@ -619,7 +657,8 @@ void flash_print_info (flash_info_t * info)
info->erase_blk_tout,
info->write_tout);
if (info->buffer_size > 1) {
- printf (" Buffer write timeout: %ld ms, buffer size: %d bytes\n",
+ printf (" Buffer write timeout: %ld ms, "
+ "buffer size: %d bytes\n",
info->buffer_write_tout,
info->buffer_size);
}
@@ -836,7 +875,9 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
/*
* flash_is_busy - check to see if the flash is busy
- * This routine checks the status of the chip and returns true if the chip is busy
+ *
+ * This routine checks the status of the chip and returns true if the
+ * chip is busy.
*/
static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
{
@@ -890,7 +931,9 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
}
/*-----------------------------------------------------------------------
- * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
+ * Wait for XSR.7 to be set, if it times out print an error, otherwise
+ * do a full status check.
+ *
* This routine sets the flash to read-array mode.
*/
static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
@@ -907,12 +950,15 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
retcode = ERR_INVAL;
printf ("Flash %s error at address %lx\n", prompt,
info->start[sector]);
- if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
+ if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS |
+ FLASH_STATUS_PSLBS)) {
puts ("Command Sequence Error.\n");
- } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
+ } else if (flash_isset (info, sector, 0,
+ FLASH_STATUS_ECLBS)) {
puts ("Block Erase Error.\n");
retcode = ERR_NOT_ERASED;
- } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
+ } else if (flash_isset (info, sector, 0,
+ FLASH_STATUS_PSLBS)) {
puts ("Locking Error\n");
}
if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
@@ -994,7 +1040,8 @@ static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
/*
* Write a proper sized command to the correct address
*/
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd)
{
volatile cfiptr_t addr;
@@ -1048,7 +1095,8 @@ static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
/*-----------------------------------------------------------------------
*/
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_isequal (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
@@ -1093,7 +1141,8 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, u
/*-----------------------------------------------------------------------
*/
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_isset (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
@@ -1123,7 +1172,8 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uch
/*-----------------------------------------------------------------------
*/
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+static int flash_toggle (flash_info_t * info, flash_sect_t sect,
+ uint offset, uchar cmd)
{
cfiptr_t cptr;
cfiword_t cword;
@@ -1204,58 +1254,69 @@ static void flash_read_jedec_ids (flash_info_t * info)
/*-----------------------------------------------------------------------
* detect if flash is compatible with the Common Flash Interface (CFI)
* http://www.jedec.org/download/search/jesd68.pdf
- *
-*/
-static int flash_detect_cfi (flash_info_t * info)
+ */
+static int __flash_detect_cfi (flash_info_t * info)
{
int cfi_offset;
+
+ flash_write_cmd (info, 0, 0, info->cmd_reset);
+ for (cfi_offset=0;
+ cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
+ cfi_offset++) {
+ flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
+ FLASH_CMD_CFI);
+ if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
+ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
+ && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+ info->interface = flash_read_ushort (info, 0,
+ FLASH_OFFSET_INTERFACE);
+ info->cfi_offset = flash_offset_cfi[cfi_offset];
+ debug ("device interface is %d\n",
+ info->interface);
+ debug ("found port %d chip %d ",
+ info->portwidth, info->chipwidth);
+ debug ("port %d bits chip %d bits\n",
+ info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+ info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+
+ /* calculate command offsets as in the Linux driver */
+ info->addr_unlock1 = 0x555;
+ info->addr_unlock2 = 0x2aa;
+
+ /*
+ * modify the unlock address if we are
+ * in compatibility mode
+ */
+ if ( /* x8/x16 in x8 mode */
+ ((info->chipwidth == FLASH_CFI_BY8) &&
+ (info->interface == FLASH_CFI_X8X16)) ||
+ /* x16/x32 in x16 mode */
+ ((info->chipwidth == FLASH_CFI_BY16) &&
+ (info->interface == FLASH_CFI_X16X32)))
+ {
+ info->addr_unlock1 = 0xaaa;
+ info->addr_unlock2 = 0x555;
+ }
+
+ info->name = "CFI conformant";
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int flash_detect_cfi (flash_info_t * info)
+{
debug ("flash detect cfi\n");
for (info->portwidth = CFG_FLASH_CFI_WIDTH;
info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
for (info->chipwidth = FLASH_CFI_BY8;
info->chipwidth <= info->portwidth;
- info->chipwidth <<= 1) {
- flash_write_cmd (info, 0, 0, info->cmd_reset);
- for (cfi_offset=0; cfi_offset < sizeof(flash_offset_cfi)/sizeof(uint); cfi_offset++) {
- flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset], FLASH_CMD_CFI);
- if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
- && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
- && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
- info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
- info->cfi_offset=flash_offset_cfi[cfi_offset];
- debug ("device interface is %d\n",
- info->interface);
- debug ("found port %d chip %d ",
- info->portwidth, info->chipwidth);
- debug ("port %d bits chip %d bits\n",
- info->portwidth << CFI_FLASH_SHIFT_WIDTH,
- info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-
- /* calculate command offsets as in the Linux driver */
- info->addr_unlock1 = 0x555;
- info->addr_unlock2 = 0x2aa;
-
- /*
- * modify the unlock address if we are
- * in compatibility mode
- */
- if ( /* x8/x16 in x8 mode */
- ((info->chipwidth == FLASH_CFI_BY8) &&
- (info->interface == FLASH_CFI_X8X16)) ||
- /* x16/x32 in x16 mode */
- ((info->chipwidth == FLASH_CFI_BY16) &&
- (info->interface == FLASH_CFI_X16X32)))
- {
- info->addr_unlock1 = 0xaaa;
- info->addr_unlock2 = 0x555;
- }
-
- info->name = "CFI conformant";
- return 1;
- }
- }
- }
+ info->chipwidth <<= 1)
+ if (__flash_detect_cfi(info))
+ return 1;
}
debug ("not found\n");
return 0;
@@ -1386,7 +1447,8 @@ ulong flash_get_size (ulong base, int banknum)
sector += (erase_region_size * size_ratio);
/*
- * Only read protection status from supported devices (intel...)
+ * Only read protection status from
+ * supported devices (intel...)
*/
switch (info->vendor) {
case CFI_CMDSET_INTEL_EXTENDED:
@@ -1397,7 +1459,8 @@ ulong flash_get_size (ulong base, int banknum)
FLASH_STATUS_PROTECT);
break;
default:
- info->protect[sect_cnt] = 0; /* default: not protected */
+ /* default: not protected */
+ info->protect[sect_cnt] = 0;
}
sect_cnt++;
@@ -1405,20 +1468,28 @@ ulong flash_get_size (ulong base, int banknum)
}
info->sector_count = sect_cnt;
+ info->size = 1 << flash_read_uchar (info, FLASH_OFFSET_SIZE);
/* multiply the size by the number of chips */
- info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
- info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE));
+ info->size *= size_ratio;
+ info->buffer_size = 1 << flash_read_ushort (info, 0,
+ FLASH_OFFSET_BUFFER_SIZE);
tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
- info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
+ info->erase_blk_tout = tmp *
+ (1 << flash_read_uchar (
+ info, FLASH_OFFSET_EMAX_TOUT));
tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT)) *
(1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT));
- info->buffer_write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
+ /* round up when converting to ms */
+ info->buffer_write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0);
tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) *
(1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT));
- info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */
+ /* round up when converting to ms */
+ info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0);
info->flash_id = FLASH_MAN_CFI;
- if ((info->interface == FLASH_CFI_X8X16) && (info->chipwidth == FLASH_CFI_BY8)) {
- info->portwidth >>= 1; /* XXX - Need to test on x8/x16 in parallel. */
+ if ((info->interface == FLASH_CFI_X8X16) &&
+ (info->chipwidth == FLASH_CFI_BY8)) {
+ /* XXX - Need to test on x8/x16 in parallel. */
+ info->portwidth >>= 1;
}
}
@@ -1426,9 +1497,8 @@ ulong flash_get_size (ulong base, int banknum)
return (info->size);
}
-/* loop through the sectors from the highest address
- * when the passed address is greater or equal to the sector address
- * we have a match
+/* loop through the sectors from the highest address when the passed
+ * address is greater or equal to the sector address we have a match
*/
static flash_sect_t find_sector (flash_info_t * info, ulong addr)
{
@@ -1534,9 +1604,12 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
sector = find_sector (info, dest);
flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
- if ((retcode = flash_status_check (info, sector, info->buffer_write_tout,
- "write to buffer")) == ERR_OK) {
- /* reduce the number of loops by the width of the port */
+ retcode = flash_status_check (info, sector,
+ info->buffer_write_tout,
+ "write to buffer");
+ if (retcode == ERR_OK) {
+ /* reduce the number of loops by the width of
+ * the port */
switch (info->portwidth) {
case FLASH_CFI_8BIT:
cnt = len;
@@ -1576,9 +1649,9 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
}
flash_write_cmd (info, sector, 0,
FLASH_CMD_WRITE_BUFFER_CONFIRM);
- retcode = flash_full_status_check (info, sector,
- info->buffer_write_tout,
- "buffer write");
+ retcode = flash_full_status_check (
+ info, sector, info->buffer_write_tout,
+ "buffer write");
}
return retcode;
@@ -1617,7 +1690,8 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
}
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
- retcode = flash_full_status_check (info, sector, info->buffer_write_tout,
+ retcode = flash_full_status_check (info, sector,
+ info->buffer_write_tout,
"buffer write");
return retcode;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 2/7] cfi_flash: Make some needlessly global functions static
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 1/7] cfi_flash: Break long lines Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 3/7] cfi_flash: Reorder functions and eliminate extra prototypes Haavard Skinnemoen
0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
Make functions not declared in any header file static.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mtd/cfi_flash.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index c73b74a..c48940b 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -212,7 +212,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest,
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
-inline uchar *
+static inline uchar *
flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
{
return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
@@ -222,7 +222,7 @@ flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
/*-----------------------------------------------------------------------
* Debug support
*/
-void print_longlong (char *str, unsigned long long data)
+static void print_longlong (char *str, unsigned long long data)
{
int i;
char *cp;
@@ -261,7 +261,7 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
/*-----------------------------------------------------------------------
* read a character at a port width address
*/
-inline uchar flash_read_uchar (flash_info_t * info, uint offset)
+static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
{
uchar *cp;
@@ -276,7 +276,8 @@ inline uchar flash_read_uchar (flash_info_t * info, uint offset)
/*-----------------------------------------------------------------------
* read a short word by swapping for ppc format.
*/
-ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
+static ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect,
+ uint offset)
{
uchar *addr;
ushort retval;
@@ -308,7 +309,8 @@ ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
* read a long word by picking the least significant byte of each maximum
* port size word. Swap for ppc format.
*/
-ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
+static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
+ uint offset)
{
uchar *addr;
ulong retval;
@@ -345,7 +347,7 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
* board_flash_get_legacy needs to fill in at least:
* info->portwidth, info->chipwidth and info->interface for Jedec probing.
*/
-int flash_detect_legacy(ulong base, int banknum)
+static int flash_detect_legacy(ulong base, int banknum)
{
flash_info_t *info = &flash_info[banknum];
@@ -397,7 +399,7 @@ int flash_detect_legacy(ulong base, int banknum)
return 0; /* use CFI */
}
#else
-int inline flash_detect_legacy(ulong base, int banknum)
+static inline int flash_detect_legacy(ulong base, int banknum)
{
return 0; /* use CFI */
}
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 3/7] cfi_flash: Reorder functions and eliminate extra prototypes
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 2/7] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 4/7] Implement __raw_{read, write}[bwl] on all architectures Haavard Skinnemoen
0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
Reorder the functions in cfi_flash.c so that each function only uses
functions that have been defined before it. This allows the static
prototype declarations near the top to be eliminated and might allow
gcc to do a better job inlining functions.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mtd/cfi_flash.c | 1343 +++++++++++++++++++++++------------------------
1 files changed, 656 insertions(+), 687 deletions(-)
This patch is too large for the mailing list. You can grab it here:
http://avr32linux.org/twiki/pub/Sandbox/UbootCfiCleanup/0003-cfi_flash-Reorder-functions-and-eliminate-extra-pro.patch
^ permalink raw reply [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 4/7] Implement __raw_{read, write}[bwl] on all architectures
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 3/7] cfi_flash: Reorder functions and eliminate extra prototypes Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 5/7] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
This adds implementations of __raw_read[bwl] and __raw_write[bwl] to
m68k, ppc, nios and nios2. The m68k and ppc implementations were taken
from Linux.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
include/asm-m68k/io.h | 14 ++++++++++++++
include/asm-nios/io.h | 8 ++++++++
include/asm-nios2/io.h | 8 ++++++++
include/asm-ppc/io.h | 32 +++++++++++++++++++++++++++++++-
4 files changed, 61 insertions(+), 1 deletions(-)
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index e14a581..29b3972 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -28,6 +28,20 @@
#include <asm/byteorder.h>
+/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
+ * two accesses to memory, which may be undesirable for some devices.
+ */
+#define __raw_readb(addr) \
+ ({ u8 __v = (*(volatile u8 *) (addr)); __v; })
+#define __raw_readw(addr) \
+ ({ u16 __v = (*(volatile u16 *) (addr)); __v; })
+#define __raw_readl(addr) \
+ ({ u32 __v = (*(volatile u32 *) (addr)); __v; })
+
+#define __raw_writeb(addr,b) (void)((*(volatile u8 *) (addr)) = (b))
+#define __raw_writew(addr,w) (void)((*(volatile u16 *) (addr)) = (w))
+#define __raw_writel(addr,l) (void)((*(volatile u32 *) (addr)) = (l))
+
#define readb(addr) in_8((volatile u8 *)(addr))
#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
#if !defined(__BIG_ENDIAN)
diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h
index d77695a..08e46a3 100644
--- a/include/asm-nios/io.h
+++ b/include/asm-nios/io.h
@@ -23,6 +23,14 @@
#ifndef __ASM_NIOS_IO_H_
#define __ASM_NIOS_IO_H_
+#define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
+#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v))
+#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v))
+
+#define __raw_readb(a) (*(volatile unsigned char *)(a))
+#define __raw_readw(a) (*(volatile unsigned short *)(a))
+#define __raw_readl(a) (*(volatile unsigned int *)(a))
+
#define readb(addr)\
({unsigned char val;\
asm volatile( " pfxio 0 \n"\
diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h
index 5bb5322..54cbd57 100644
--- a/include/asm-nios2/io.h
+++ b/include/asm-nios2/io.h
@@ -33,6 +33,14 @@ extern unsigned char inb (unsigned char *port);
extern unsigned short inw (unsigned short *port);
extern unsigned inl (unsigned port);
+#define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
+#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v))
+#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v))
+
+#define __raw_readb(a) (*(volatile unsigned char *)(a))
+#define __raw_readw(a) (*(volatile unsigned short *)(a))
+#define __raw_readl(a) (*(volatile unsigned int *)(a))
+
#define readb(addr)\
({unsigned char val;\
asm volatile( "ldbio %0, 0(%1)" :"=r"(val) : "r" (addr)); val;})
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 11dfa1c..86fe8dc 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -121,13 +121,43 @@ static inline void isync(void)
#define iobarrier_w() eieio()
/*
+ * Non ordered and non-swapping "raw" accessors
+ */
+#define __iomem
+#define PCI_FIX_ADDR(addr) (addr)
+
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned char *)PCI_FIX_ADDR(addr);
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned short *)PCI_FIX_ADDR(addr);
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+ return *(volatile unsigned int *)PCI_FIX_ADDR(addr);
+}
+static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+{
+ *(volatile unsigned char *)PCI_FIX_ADDR(addr) = v;
+}
+static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
+{
+ *(volatile unsigned short *)PCI_FIX_ADDR(addr) = v;
+}
+static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
+{
+ *(volatile unsigned int *)PCI_FIX_ADDR(addr) = v;
+}
+
+/*
* 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
*
* Read operations have additional twi & isync to make sure the read
* is actually performed (i.e. the data has come back) before we start
* executing any following instructions.
*/
-#define __iomem
extern inline int in_8(const volatile unsigned char __iomem *addr)
{
int ret;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 5/7] cfi_flash: Introduce read and write accessors
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 4/7] Implement __raw_{read, write}[bwl] on all architectures Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 6/7] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
Introduce flash_read{8,16,32,64) and flash_write{8,16,32,64} and use
them to access the flash memory. This makes it clearer when the flash
is actually being accessed; merely dereferencing a volatile pointer
looks just like any other kind of access.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mtd/cfi_flash.c | 205 +++++++++++++++++++++++++++++------------------
1 files changed, 127 insertions(+), 78 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index a89fcae..d33725d 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -149,13 +149,6 @@ typedef union {
unsigned long long ll;
} cfiword_t;
-typedef union {
- volatile unsigned char *cp;
- volatile unsigned short *wp;
- volatile unsigned long *lp;
- volatile unsigned long long *llp;
-} cfiptr_t;
-
#define NUM_ERASE_REGIONS 4 /* max. number of erase regions */
static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
@@ -178,6 +171,48 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* FLASH chips info */
typedef unsigned long flash_sect_t;
+static void flash_write8(u8 value, void *addr)
+{
+ __raw_writeb(value, addr);
+}
+
+static void flash_write16(u16 value, void *addr)
+{
+ __raw_writew(value, addr);
+}
+
+static void flash_write32(u32 value, void *addr)
+{
+ __raw_writel(value, addr);
+}
+
+static void flash_write64(u64 value, void *addr)
+{
+ /* No architectures currently implement __raw_writeq() */
+ *(volatile u64 *)addr = value;
+}
+
+static u8 flash_read8(void *addr)
+{
+ return __raw_readb(addr);
+}
+
+static u16 flash_read16(void *addr)
+{
+ return __raw_readw(addr);
+}
+
+static u32 flash_read32(void *addr)
+{
+ return __raw_readl(addr);
+}
+
+static u64 flash_read64(void *addr)
+{
+ /* No architectures currently implement __raw_readq() */
+ return *(volatile u64 *)addr;
+}
+
/*-----------------------------------------------------------------------
*/
#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
@@ -238,21 +273,21 @@ static void print_longlong (char *str, unsigned long long data)
static void flash_printqry (flash_info_t * info, flash_sect_t sect)
{
- cfiptr_t cptr;
+ void *addr;
int x, y;
for (x = 0; x < 0x40; x += 16U / info->portwidth) {
- cptr.cp =
- flash_make_addr (info, sect,
- x + FLASH_OFFSET_CFI_RESP);
- debug ("%p : ", cptr.cp);
+ addr = flash_make_addr (info, sect,
+ x + FLASH_OFFSET_CFI_RESP);
+ debug ("%p : ", addr);
for (y = 0; y < 16; y++) {
- debug ("%2.2x ", cptr.cp[y]);
+ debug ("%2.2x ", flash_read8(addr + y));
}
debug (" ");
for (y = 0; y < 16; y++) {
- if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
- debug ("%c", cptr.cp[y]);
+ unsigned char c = flash_read8(addr + y);
+ if (c >= 0x20 && c <= 0x7e) {
+ debug ("%c", c);
} else {
debug (".");
}
@@ -352,28 +387,28 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
uint offset, uchar cmd)
{
- volatile cfiptr_t addr;
+ void *addr;
cfiword_t cword;
- addr.cp = flash_make_addr (info, sect, offset);
+ addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
+ debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- *addr.cp = cword.c;
+ flash_write8(cword.c, addr);
break;
case FLASH_CFI_16BIT:
- debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
+ debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
cmd, cword.w,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- *addr.wp = cword.w;
+ flash_write16(cword.w, addr);
break;
case FLASH_CFI_32BIT:
- debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
+ debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr,
cmd, cword.l,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- *addr.lp = cword.l;
+ flash_write32(cword.l, addr);
break;
case FLASH_CFI_64BIT:
#ifdef DEBUG
@@ -383,11 +418,11 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
print_longlong (str, cword.ll);
debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
- addr.llp, cmd, str,
+ addr, cmd, str,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
}
#endif
- *addr.llp = cword.ll;
+ flash_write64(cword.ll, addr);
break;
}
@@ -406,26 +441,26 @@ static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
static int flash_isequal (flash_info_t * info, flash_sect_t sect,
uint offset, uchar cmd)
{
- cfiptr_t cptr;
+ void *addr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
+ addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
- debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
+ debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- debug ("is= %x %x\n", cptr.cp[0], cword.c);
- retval = (cptr.cp[0] == cword.c);
+ debug ("is= %x %x\n", flash_read8(addr), cword.c);
+ retval = (flash_read8(addr) == cword.c);
break;
case FLASH_CFI_16BIT:
- debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
- retval = (cptr.wp[0] == cword.w);
+ debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
+ retval = (flash_read16(addr) == cword.w);
break;
case FLASH_CFI_32BIT:
- debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
- retval = (cptr.lp[0] == cword.l);
+ debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
+ retval = (flash_read32(addr) == cword.l);
break;
case FLASH_CFI_64BIT:
#ifdef DEBUG
@@ -433,12 +468,12 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
char str1[20];
char str2[20];
- print_longlong (str1, cptr.llp[0]);
+ print_longlong (str1, flash_read64(addr));
print_longlong (str2, cword.ll);
debug ("is= %s %s\n", str1, str2);
}
#endif
- retval = (cptr.llp[0] == cword.ll);
+ retval = (flash_read64(addr) == cword.ll);
break;
default:
retval = 0;
@@ -452,24 +487,24 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
static int flash_isset (flash_info_t * info, flash_sect_t sect,
uint offset, uchar cmd)
{
- cfiptr_t cptr;
+ void *addr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
+ addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- retval = ((cptr.cp[0] & cword.c) == cword.c);
+ retval = ((flash_read8(addr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
- retval = ((cptr.wp[0] & cword.w) == cword.w);
+ retval = ((flash_read16(addr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- retval = ((cptr.lp[0] & cword.l) == cword.l);
+ retval = ((flash_read16(addr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
- retval = ((cptr.llp[0] & cword.ll) == cword.ll);
+ retval = ((flash_read64(addr) & cword.ll) == cword.ll);
break;
default:
retval = 0;
@@ -483,25 +518,28 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
static int flash_toggle (flash_info_t * info, flash_sect_t sect,
uint offset, uchar cmd)
{
- cfiptr_t cptr;
+ void *addr;
cfiword_t cword;
int retval;
- cptr.cp = flash_make_addr (info, sect, offset);
+ addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
+ retval = ((flash_read8(addr) & cword.c) !=
+ (flash_read8(addr) & cword.c));
break;
case FLASH_CFI_16BIT:
- retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
+ retval = ((flash_read16(addr) & cword.w) !=
+ (flash_read16(addr) & cword.w));
break;
case FLASH_CFI_32BIT:
- retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
+ retval = ((flash_read32(addr) & cword.l) !=
+ (flash_read32(addr) & cword.l));
break;
case FLASH_CFI_64BIT:
- retval = ((cptr.llp[0] & cword.ll) !=
- (cptr.llp[0] & cword.ll));
+ retval = ((flash_read64(addr) & cword.ll) !=
+ (flash_read64(addr) & cword.ll));
break;
default:
retval = 0;
@@ -676,26 +714,26 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
static int flash_write_cfiword (flash_info_t * info, ulong dest,
cfiword_t cword)
{
- cfiptr_t ctladdr;
- cfiptr_t cptr;
+ void *ctladdr;
+ void *dstaddr;
int flag;
- ctladdr.cp = flash_make_addr (info, 0, 0);
- cptr.cp = (uchar *) dest;
+ ctladdr = flash_make_addr (info, 0, 0);
+ dstaddr = (uchar *)dest;
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- flag = ((cptr.cp[0] & cword.c) == cword.c);
+ flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
- flag = ((cptr.wp[0] & cword.w) == cword.w);
+ flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- flag = ((cptr.lp[0] & cword.l) == cword.l);
+ flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
- flag = ((cptr.llp[0] & cword.ll) == cword.ll);
+ flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
return 2;
@@ -724,16 +762,16 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- cptr.cp[0] = cword.c;
+ flash_write8(cword.c, dstaddr);
break;
case FLASH_CFI_16BIT:
- cptr.wp[0] = cword.w;
+ flash_write16(cword.w, dstaddr);
break;
case FLASH_CFI_32BIT:
- cptr.lp[0] = cword.l;
+ flash_write32(cword.l, dstaddr);
break;
case FLASH_CFI_64BIT:
- cptr.llp[0] = cword.ll;
+ flash_write64(cword.ll, dstaddr);
break;
}
@@ -753,15 +791,14 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
flash_sect_t sector;
int cnt;
int retcode;
- volatile cfiptr_t src;
- volatile cfiptr_t dst;
+ void *src = cp;
+ void *dst = (void *)dest;
+
+ sector = find_sector (info, dest);
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
- src.cp = cp;
- dst.cp = (uchar *) dest;
- sector = find_sector (info, dest);
flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
retcode = flash_status_check (info, sector,
@@ -791,16 +828,20 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
while (cnt-- > 0) {
switch (info->portwidth) {
case FLASH_CFI_8BIT:
- *dst.cp++ = *src.cp++;
+ flash_write8(flash_read8(src), dst);
+ src += 1, dst += 1;
break;
case FLASH_CFI_16BIT:
- *dst.wp++ = *src.wp++;
+ flash_write16(flash_read16(src), dst);
+ src += 2, dst += 2;
break;
case FLASH_CFI_32BIT:
- *dst.lp++ = *src.lp++;
+ flash_write32(flash_read32(src), dst);
+ src += 4, dst += 4;
break;
case FLASH_CFI_64BIT:
- *dst.llp++ = *src.llp++;
+ flash_write64(flash_read64(src), dst);
+ src += 8, dst += 8;
break;
default:
return ERR_INVAL;
@@ -817,10 +858,6 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
- src.cp = cp;
- dst.cp = (uchar *) dest;
- sector = find_sector (info, dest);
-
flash_unlock_seq(info,0);
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
@@ -828,22 +865,34 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
case FLASH_CFI_8BIT:
cnt = len;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
- while (cnt-- > 0) *dst.cp++ = *src.cp++;
+ while (cnt-- > 0) {
+ flash_write8(flash_read8(src), dst);
+ src += 1, dst += 1;
+ }
break;
case FLASH_CFI_16BIT:
cnt = len >> 1;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
- while (cnt-- > 0) *dst.wp++ = *src.wp++;
+ while (cnt-- > 0) {
+ flash_write16(flash_read16(src), dst);
+ src += 2, dst += 2;
+ }
break;
case FLASH_CFI_32BIT:
cnt = len >> 2;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
- while (cnt-- > 0) *dst.lp++ = *src.lp++;
+ while (cnt-- > 0) {
+ flash_write32(flash_read32(src), dst);
+ src += 4, dst += 4;
+ }
break;
case FLASH_CFI_64BIT:
cnt = len >> 3;
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
- while (cnt-- > 0) *dst.llp++ = *src.llp++;
+ while (cnt-- > 0) {
+ flash_write64(flash_read64(src), dst);
+ src += 8, dst += 8;
+ }
break;
default:
return ERR_INVAL;
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 6/7] Introduce map_physmem() and unmap_physmem()
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 5/7] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 7/7] cfi_flash: Use " Haavard Skinnemoen
0 siblings, 1 reply; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
map_physmem() returns a virtual address which can be used to access a
given physical address without involving the cache. unmap_physmem()
should be called when the virtual address returned by map_physmem() is
no longer needed.
This patch adds a stub implementation which simply returns the
physical address cast to a uchar * for all architectures except AVR32,
which converts the physical address to an uncached virtual mapping.
unmap_physmem() is a no-op on all architectures, but if any
architecture needs to do such mappings through the TLB, this is the
hook where those TLB entries can be invalidated.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
include/asm-arm/io.h | 26 ++++++++++++++++++++++++++
include/asm-avr32/io.h | 32 ++++++++++++++++++++++++++++++++
include/asm-blackfin/io.h | 26 ++++++++++++++++++++++++++
include/asm-i386/io.h | 26 ++++++++++++++++++++++++++
include/asm-m68k/io.h | 27 +++++++++++++++++++++++++++
include/asm-microblaze/io.h | 26 ++++++++++++++++++++++++++
include/asm-mips/io.h | 26 ++++++++++++++++++++++++++
include/asm-nios/io.h | 26 ++++++++++++++++++++++++++
include/asm-nios2/io.h | 26 ++++++++++++++++++++++++++
include/asm-ppc/io.h | 26 ++++++++++++++++++++++++++
10 files changed, 267 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 47c18e7..029b7f9 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -34,6 +34,32 @@ static inline void sync(void)
}
/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
+/*
* Generic virtual read/write. Note that we don't support half-word
* read/writes. We define __arch_*[bl] here, and leave __arch_*w
* to the architecture specific code.
diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index 3c0d569..ba14674 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -93,4 +93,36 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ *
+ * This implementation works for memory below 512MiB (flash, etc.) as
+ * well as above 3.5GiB (internal peripherals.)
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (1 << 7)
+#define MAP_WRBACK (MAP_WRCOMBINE | (1 << 9))
+#define MAP_WRTHROUGH (MAP_WRBACK | (1 << 0))
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ if (flags == MAP_WRBACK)
+ return (void *)P1SEGADDR(paddr);
+ else
+ return (void *)P2SEGADDR(paddr);
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long len)
+{
+
+}
+
#endif /* __ASM_AVR32_IO_H */
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h
index 332d2c6..512e13d 100644
--- a/include/asm-blackfin/io.h
+++ b/include/asm-blackfin/io.h
@@ -41,6 +41,32 @@ static inline void sync(void)
}
/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
+/*
* These are for ISA/PCI shared memory _only_ and should never be used
* on any other type of memory, including Zorro memory. They are meant to
* access the bus in the bus byte order which is little-endian!.
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index e64d788..db4f442 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -205,4 +205,30 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index 29b3972..91d7592 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -232,4 +232,31 @@ static inline void sync(void)
* compatibility (CFI driver)
*/
}
+
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif /* __ASM_M68K_IO_H__ */
diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h
index 1c77ade..90d1842 100644
--- a/include/asm-microblaze/io.h
+++ b/include/asm-microblaze/io.h
@@ -129,4 +129,30 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif /* __MICROBLAZE_IO_H__ */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 1e060f7..e27d1f1 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -465,4 +465,30 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif /* _ASM_IO_H */
diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h
index 08e46a3..6fc339f 100644
--- a/include/asm-nios/io.h
+++ b/include/asm-nios/io.h
@@ -109,4 +109,30 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif /* __ASM_NIOS_IO_H_ */
diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h
index 54cbd57..a52b95c 100644
--- a/include/asm-nios2/io.h
+++ b/include/asm-nios2/io.h
@@ -29,6 +29,32 @@ static inline void sync(void)
__asm__ __volatile__ ("sync" : : : "memory");
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
extern unsigned char inb (unsigned char *port);
extern unsigned short inw (unsigned short *port);
extern unsigned inl (unsigned port);
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 86fe8dc..91c9c1e 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -238,4 +238,30 @@ extern inline void out_be32(volatile unsigned __iomem *addr, int val)
__asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE (0)
+#define MAP_WRCOMBINE (0)
+#define MAP_WRBACK (0)
+#define MAP_WRTHROUGH (0)
+
+static inline void *
+map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
#endif
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 7/7] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 6/7] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
@ 2007-12-13 11:56 ` Haavard Skinnemoen
0 siblings, 0 replies; 9+ messages in thread
From: Haavard Skinnemoen @ 2007-12-13 11:56 UTC (permalink / raw)
To: u-boot
Use map_physmem() and unmap_physmem() to convert from physical to
virtual addresses. This gives the arch a chance to provide an uncached
mapping for flash accesses.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/mtd/cfi_flash.c | 169 ++++++++++++++++++++++++++++++-----------------
1 files changed, 109 insertions(+), 60 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index d33725d..6c18252 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -232,13 +232,33 @@ static flash_info_t *flash_get_info(ulong base)
}
#endif
+unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)
+{
+ if (sect != (info->sector_count - 1))
+ return info->start[sect + 1] - info->start[sect];
+ else
+ return info->start[0] + info->size - info->start[sect];
+}
+
/*-----------------------------------------------------------------------
* create an address based on the offset and the port width
*/
-static inline uchar *
-flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
+static inline void *
+flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
{
- return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
+ unsigned int byte_offset = offset * info->portwidth;
+
+ return map_physmem(info->start[sect] + byte_offset,
+ flash_sector_size(info, sect) - byte_offset,
+ MAP_NOCACHE);
+}
+
+static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
+ unsigned int offset, void *addr)
+{
+ unsigned int byte_offset = offset * info->portwidth;
+
+ unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);
}
/*-----------------------------------------------------------------------
@@ -277,8 +297,7 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
int x, y;
for (x = 0; x < 0x40; x += 16U / info->portwidth) {
- addr = flash_make_addr (info, sect,
- x + FLASH_OFFSET_CFI_RESP);
+ addr = flash_map(info, sect, x + FLASH_OFFSET_CFI_RESP);
debug ("%p : ", addr);
for (y = 0; y < 16; y++) {
debug ("%2.2x ", flash_read8(addr + y));
@@ -293,6 +312,7 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
}
}
debug ("\n");
+ flash_unmap(info, sect, x + FLASH_OFFSET_CFI_RESP, addr);
}
}
#endif
@@ -304,13 +324,16 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
{
uchar *cp;
+ uchar retval;
- cp = flash_make_addr (info, 0, offset);
+ cp = flash_map (info, 0, offset);
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
- return (cp[0]);
+ retval = flash_read8(cp);
#else
- return (cp[info->portwidth - 1]);
+ retval = flash_read8(cp + info->portwidth - 1);
#endif
+ flash_unmap (info, 0, offset, cp);
+ return retval;
}
/*-----------------------------------------------------------------------
@@ -325,23 +348,26 @@ static ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect,
#ifdef DEBUG
int x;
#endif
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
#ifdef DEBUG
debug ("ushort addr is at %p info->portwidth = %d\n", addr,
info->portwidth);
for (x = 0; x < 2 * info->portwidth; x++) {
- debug ("addr[%x] = 0x%x\n", x, addr[x]);
+ debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
}
#endif
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
- retval = ((addr[(info->portwidth)] << 8) | addr[0]);
+ retval = ((flash_read8(addr + info->portwidth) << 8) |
+ flash_read8(addr));
#else
- retval = ((addr[(2 * info->portwidth) - 1] << 8) |
- addr[info->portwidth - 1]);
+ retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 8) |
+ flash_read8(addr + info->portwidth - 1));
#endif
debug ("retval = 0x%x\n", retval);
+ flash_unmap (info, sect, offset, addr);
+
return retval;
}
@@ -358,25 +384,28 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
#ifdef DEBUG
int x;
#endif
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
#ifdef DEBUG
debug ("long addr is at %p info->portwidth = %d\n", addr,
info->portwidth);
for (x = 0; x < 4 * info->portwidth; x++) {
- debug ("addr[%x] = 0x%x\n", x, addr[x]);
+ debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
}
#endif
#if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
- retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
- (addr[(2 * info->portwidth)]) |
- (addr[(3 * info->portwidth)] << 8);
+ retval = ((flash_read8(addr) << 16) |
+ (flash_read8(addr + info->portwidth) << 24) |
+ (flash_read8(addr + 2 * info->portwidth)) |
+ (flash_read8(addr + 3 * info->portwidth) << 8));
#else
- retval = (addr[(2 * info->portwidth) - 1] << 24) |
- (addr[(info->portwidth) - 1] << 16) |
- (addr[(4 * info->portwidth) - 1] << 8) |
- addr[(3 * info->portwidth) - 1];
+ retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 24) |
+ (flash_read8(addr + info->portwidth - 1) << 16) |
+ (flash_read8(addr + 4 * info->portwidth - 1) << 8) |
+ (flash_read8(addr + 3 * info->portwidth - 1)));
#endif
+ flash_unmap(info, sect, offset, addr);
+
return retval;
}
@@ -390,7 +419,7 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
void *addr;
cfiword_t cword;
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -428,6 +457,8 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
/* Ensure all the instructions are fully finished */
sync();
+
+ flash_unmap(info, sect, offset, addr);
}
static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
@@ -445,7 +476,7 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
cfiword_t cword;
int retval;
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
@@ -479,6 +510,8 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(info, sect, offset, addr);
+
return retval;
}
@@ -491,7 +524,7 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
cfiword_t cword;
int retval;
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -510,6 +543,8 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(info, sect, offset, addr);
+
return retval;
}
@@ -522,7 +557,7 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
cfiword_t cword;
int retval;
- addr = flash_make_addr (info, sect, offset);
+ addr = flash_map (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
@@ -545,6 +580,8 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(info, sect, offset, addr);
+
return retval;
}
@@ -714,12 +751,10 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
static int flash_write_cfiword (flash_info_t * info, ulong dest,
cfiword_t cword)
{
- void *ctladdr;
void *dstaddr;
int flag;
- ctladdr = flash_make_addr (info, 0, 0);
- dstaddr = (uchar *)dest;
+ dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
@@ -736,10 +771,13 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
- return 2;
+ flag = 0;
+ break;
}
- if (!flag)
+ if (!flag) {
+ unmap_physmem(dstaddr, info->portwidth);
return 2;
+ }
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
@@ -779,6 +817,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
if (flag)
enable_interrupts ();
+ unmap_physmem(dstaddr, info->portwidth);
+
return flash_full_status_check (info, find_sector (info, dest),
info->write_tout, "write");
}
@@ -792,7 +832,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
int cnt;
int retcode;
void *src = cp;
- void *dst = (void *)dest;
+ void *dst = map_physmem(dest, len, MAP_NOCACHE);
sector = find_sector (info, dest);
@@ -821,8 +861,8 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
cnt = len >> 3;
break;
default:
- return ERR_INVAL;
- break;
+ retcode = ERR_INVAL;
+ goto out_unmap;
}
flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
while (cnt-- > 0) {
@@ -844,8 +884,8 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
src += 8, dst += 8;
break;
default:
- return ERR_INVAL;
- break;
+ retcode = ERR_INVAL;
+ goto out_unmap;
}
}
flash_write_cmd (info, sector, 0,
@@ -854,7 +894,8 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
info, sector, info->buffer_write_tout,
"buffer write");
}
- return retcode;
+
+ break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
@@ -895,19 +936,25 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
}
break;
default:
- return ERR_INVAL;
+ retcode = ERR_INVAL;
+ goto out_unmap;
}
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check (info, sector,
info->buffer_write_tout,
"buffer write");
- return retcode;
+ break;
default:
debug ("Unknown Command Set\n");
- return ERR_INVAL;
+ retcode = ERR_INVAL;
+ break;
}
+
+out_unmap:
+ unmap_physmem(dst, len);
+ return retcode;
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
@@ -1063,10 +1110,7 @@ void flash_print_info (flash_info_t * info)
/*
* Check if whole sector is erased
*/
- if (i != (info->sector_count - 1))
- size = info->start[i + 1] - info->start[i];
- else
- size = info->start[0] + info->size - info->start[i];
+ size = flash_sector_size(info, i);
erased = 1;
flash = (volatile unsigned long *) info->start[i];
size = size >> 2; /* divide by 4 for longword access */
@@ -1101,7 +1145,7 @@ void flash_print_info (flash_info_t * info)
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong wp;
- ulong cp;
+ uchar *p;
int aln;
cfiword_t cword;
int i, rc;
@@ -1110,26 +1154,28 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
int buffered_size;
#endif
/* get lower aligned address */
- /* get lower aligned address */
wp = (addr & ~(info->portwidth - 1));
/* handle unaligned start */
if ((aln = addr - wp) != 0) {
cword.l = 0;
- cp = wp;
- for (i = 0; i < aln; ++i, ++cp)
- flash_add_byte (info, &cword, (*(uchar *) cp));
+ p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
+ for (i = 0; i < aln; ++i)
+ flash_add_byte (info, &cword, flash_read8(p + i));
for (; (i < info->portwidth) && (cnt > 0); i++) {
flash_add_byte (info, &cword, *src++);
cnt--;
- cp++;
}
- for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
- flash_add_byte (info, &cword, (*(uchar *) cp));
- if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+ for (; (cnt == 0) && (i < info->portwidth); ++i)
+ flash_add_byte (info, &cword, flash_read8(p + i));
+
+ rc = flash_write_cfiword (info, wp, cword);
+ unmap_physmem(p, info->portwidth);
+ if (rc != 0)
return rc;
- wp = cp;
+
+ wp += i;
}
/* handle the aligned part */
@@ -1180,13 +1226,14 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
* handle unaligned tail bytes
*/
cword.l = 0;
- for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
+ p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
+ for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
flash_add_byte (info, &cword, *src++);
--cnt;
}
- for (; i < info->portwidth; ++i, ++cp) {
- flash_add_byte (info, &cword, (*(uchar *) cp));
- }
+ for (; i < info->portwidth; ++i)
+ flash_add_byte (info, &cword, flash_read8(p + i));
+ unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword);
}
@@ -1238,10 +1285,11 @@ void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
uchar *dst;
dst = buffer;
- src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
+ src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);
flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
memcpy (dst, src + offset, len);
flash_write_cmd (info, 0, 0, info->cmd_reset);
+ flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
}
/*
@@ -1252,10 +1300,11 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
{
uchar *src;
- src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
+ src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
memcpy (buffer, src + offset, len);
flash_write_cmd (info, 0, 0, info->cmd_reset);
+ flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
}
#endif /* CFG_FLASH_PROTECTION */
--
1.5.3.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3
2007-12-13 11:56 [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 1/7] cfi_flash: Break long lines Haavard Skinnemoen
@ 2007-12-13 12:56 ` Stefan Roese
1 sibling, 0 replies; 9+ messages in thread
From: Stefan Roese @ 2007-12-13 12:56 UTC (permalink / raw)
To: u-boot
On Thursday 13 December 2007, Haavard Skinnemoen wrote:
> This is a resend of the whole series rebased onto the latest head of
> the CFI tree.
OK, I applied this patch series to the u-boot-cfi-flash custodian repository.
Tested successfully on Sequoia. No problems so far.
Please test this version on your boards. I'll send a pull request to Wolfgang
in a few days.
Thanks.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2007-12-13 12:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-13 11:56 [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 1/7] cfi_flash: Break long lines Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 2/7] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 3/7] cfi_flash: Reorder functions and eliminate extra prototypes Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 4/7] Implement __raw_{read, write}[bwl] on all architectures Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 5/7] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 6/7] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
2007-12-13 11:56 ` [U-Boot-Users] [PATCH 7/7] cfi_flash: Use " Haavard Skinnemoen
2007-12-13 12:56 ` [U-Boot-Users] [PATCH 0/7] cfi_flash cleanups, take 3 Stefan Roese
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox