* [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups
@ 2007-12-11 15:28 Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Haavard Skinnemoen
2007-12-11 19:04 ` [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Stefan Roese
0 siblings, 2 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 UTC (permalink / raw)
To: u-boot
This is a series of cleanups to the CFI driver I did while debugging
why it refused to work on my AVR32 boards, rebased on top of the
latest CFI custodian tree with "[PATCH] CFI: synchronize command
offsets with Linux CFI driver" applied as well.
I'm not completely done yet, as I need more fixes to make the CFI
driver work on boards like the ATNGW100. But these initial patches are
seriously painful to rebase (especially #3 in this series,) so I'd
like some feedback from others if I'm moving in an acceptable
direction with this.
I've compile-tested the whole thing using MAKEALL on ppc (no point in
testing on avr32 since no boards use this driver yet.) mcc200 failed,
but it complains about lots of undefined symbols that has nothing to
do with the CFI driver, so I'm pretty sure it isn't my fault.
Please let me know which parts of this are acceptable, and if there's
something that can be done in a better way. And if you merge parts
1-3 (or even more of them), I'd be _very_ happy :-)
There are a couple of remaining cleanups I'd like to make that go on
top of this stuff, mostly related to refactoring the command set
handling and adding manufacturer-specific fixups.
Haavard Skinnemoen (6):
cfi_flash: Break long lines
cfi_flash: Make some needlessly global functions static
cfi_flash: Reorder functions and eliminate extra prototypes
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 | 1677 +++++++++++++++++++++++--------------------
include/asm-arm/io.h | 17 +
include/asm-avr32/io.h | 20 +
include/asm-blackfin/io.h | 17 +
include/asm-i386/io.h | 17 +
include/asm-m68k/io.h | 18 +
include/asm-microblaze/io.h | 17 +
include/asm-mips/io.h | 17 +
include/asm-nios/io.h | 17 +
include/asm-nios2/io.h | 17 +
include/asm-ppc/io.h | 17 +
11 files changed, 1077 insertions(+), 774 deletions(-)
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines
2007-12-11 15:28 [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Haavard Skinnemoen
@ 2007-12-11 15:28 ` Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 2/6] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
2007-12-13 11:04 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Stefan Roese
2007-12-11 19:04 ` [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Stefan Roese
1 sibling, 2 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 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 b748a9f..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] 25+ messages in thread
* [U-Boot-Users] [PATCH 2/6] cfi_flash: Make some needlessly global functions static
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Haavard Skinnemoen
@ 2007-12-11 15:28 ` Haavard Skinnemoen
[not found] ` <1197386900-14570-4-git-send-email-hskinnemoen@atmel.com>
2007-12-13 11:04 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Stefan Roese
1 sibling, 1 reply; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 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] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
[not found] ` <1197386900-14570-4-git-send-email-hskinnemoen@atmel.com>
@ 2007-12-11 15:28 ` Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 5/6] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
2007-12-11 15:35 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Kumar Gala
0 siblings, 2 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 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 | 203 +++++++++++++++++++++++++++++------------------
1 files changed, 125 insertions(+), 78 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index a89fcae..70a626a 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,46 @@ 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)
+{
+ *(volatile u8 *)addr = value;
+}
+
+static void flash_write16(u16 value, void *addr)
+{
+ *(volatile u16 *)addr = value;
+}
+
+static void flash_write32(u32 value, void *addr)
+{
+ *(volatile u32 *)addr = value;
+}
+
+static void flash_write64(u64 value, void *addr)
+{
+ *(volatile u64 *)addr = value;
+}
+
+static u8 flash_read8(void *addr)
+{
+ return *(volatile u8 *)addr;
+}
+
+static u16 flash_read16(void *addr)
+{
+ return *(volatile u16 *)addr;
+}
+
+static u32 flash_read32(void *addr)
+{
+ return *(volatile u32 *)addr;
+}
+
+static u64 flash_read64(void *addr)
+{
+ return *(volatile u64 *)addr;
+}
+
/*-----------------------------------------------------------------------
*/
#if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
@@ -238,21 +271,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 +385,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 +416,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 +439,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 +466,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 +485,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 +516,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 +712,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 +760,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 +789,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 +826,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 +856,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 +863,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] 25+ messages in thread
* [U-Boot-Users] [PATCH 5/6] Introduce map_physmem() and unmap_physmem()
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
@ 2007-12-11 15:28 ` Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 6/6] cfi_flash: Use " Haavard Skinnemoen
2007-12-11 15:35 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Kumar Gala
1 sibling, 1 reply; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 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 | 17 +++++++++++++++++
include/asm-avr32/io.h | 20 ++++++++++++++++++++
include/asm-blackfin/io.h | 17 +++++++++++++++++
include/asm-i386/io.h | 17 +++++++++++++++++
include/asm-m68k/io.h | 18 ++++++++++++++++++
include/asm-microblaze/io.h | 17 +++++++++++++++++
include/asm-mips/io.h | 17 +++++++++++++++++
include/asm-nios/io.h | 17 +++++++++++++++++
include/asm-nios2/io.h | 17 +++++++++++++++++
include/asm-ppc/io.h | 17 +++++++++++++++++
10 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 47c18e7..8d6b37f 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -34,6 +34,23 @@ static inline void sync(void)
}
/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
+/*
* 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..1616a00 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -93,4 +93,24 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ *
+ * This implementation works for memory below 512MiB (flash, etc.) as
+ * well as above 3.5GiB (internal peripherals.)
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)P2SEGADDR(paddr);
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif /* __ASM_AVR32_IO_H */
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h
index 332d2c6..d84f79d 100644
--- a/include/asm-blackfin/io.h
+++ b/include/asm-blackfin/io.h
@@ -41,6 +41,23 @@ static inline void sync(void)
}
/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
+/*
* 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..fa38231 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -205,4 +205,21 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index e14a581..73c1b13 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -218,4 +218,22 @@ static inline void sync(void)
* compatibility (CFI driver)
*/
}
+
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif /* __ASM_M68K_IO_H__ */
diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h
index 1c77ade..9424c83 100644
--- a/include/asm-microblaze/io.h
+++ b/include/asm-microblaze/io.h
@@ -129,4 +129,21 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif /* __MICROBLAZE_IO_H__ */
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 1e060f7..bacc288 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -465,4 +465,21 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif /* _ASM_IO_H */
diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h
index d77695a..6c88918 100644
--- a/include/asm-nios/io.h
+++ b/include/asm-nios/io.h
@@ -101,4 +101,21 @@ static inline void sync(void)
{
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif /* __ASM_NIOS_IO_H_ */
diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h
index 5bb5322..e9aae72 100644
--- a/include/asm-nios2/io.h
+++ b/include/asm-nios2/io.h
@@ -29,6 +29,23 @@ static inline void sync(void)
__asm__ __volatile__ ("sync" : : : "memory");
}
+/*
+ * Given a physical address, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
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 11dfa1c..b8442f9 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -208,4 +208,21 @@ 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, return a virtual address that can be used
+ * to access it without going through the cache.
+ */
+static inline void *map_physmem(unsigned long paddr)
+{
+ return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr)
+{
+
+}
+
#endif
--
1.5.3.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 5/6] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
@ 2007-12-11 15:28 ` Haavard Skinnemoen
2007-12-11 15:36 ` Kumar Gala
2007-12-11 22:10 ` Wolfgang Denk
0 siblings, 2 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:28 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 | 149 +++++++++++++++++++++++++++++------------------
1 files changed, 93 insertions(+), 56 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 70a626a..94208e2 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -233,10 +233,15 @@ static flash_info_t *flash_get_info(ulong base)
/*-----------------------------------------------------------------------
* 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)));
+ return map_physmem(info->start[sect] + (offset * info->portwidth));
+}
+
+static inline void flash_unmap(void *addr)
+{
+ unmap_physmem(addr);
}
/*-----------------------------------------------------------------------
@@ -275,8 +280,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));
@@ -291,6 +295,7 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
}
}
debug ("\n");
+ flash_unmap(addr);
}
}
#endif
@@ -302,13 +307,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 (cp);
+ return retval;
}
/*-----------------------------------------------------------------------
@@ -323,23 +331,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 (addr);
+
return retval;
}
@@ -356,25 +367,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(addr);
+
return retval;
}
@@ -388,7 +402,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:
@@ -426,6 +440,8 @@ static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
/* Ensure all the instructions are fully finished */
sync();
+
+ flash_unmap(addr);
}
static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
@@ -443,7 +459,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);
@@ -477,6 +493,8 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(addr);
+
return retval;
}
@@ -489,7 +507,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:
@@ -508,6 +526,8 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(addr);
+
return retval;
}
@@ -520,7 +540,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:
@@ -543,6 +563,8 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
retval = 0;
break;
}
+ flash_unmap(addr);
+
return retval;
}
@@ -712,12 +734,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);
/* Check if Flash is (sufficiently) erased */
switch (info->portwidth) {
@@ -734,10 +754,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);
return 2;
+ }
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ();
@@ -777,6 +800,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
if (flag)
enable_interrupts ();
+ unmap_physmem(dstaddr);
+
return flash_full_status_check (info, find_sector (info, dest),
info->write_tout, "write");
}
@@ -790,7 +815,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);
sector = find_sector (info, dest);
@@ -819,8 +844,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) {
@@ -842,8 +867,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,
@@ -852,7 +877,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:
@@ -893,19 +919,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);
+ return retcode;
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
@@ -1099,7 +1131,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;
@@ -1108,26 +1140,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);
+ 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);
+ if (rc != 0)
return rc;
- wp = cp;
+
+ wp += i;
}
/* handle the aligned part */
@@ -1178,13 +1212,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);
+ 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);
return flash_write_cfiword (info, wp, cword);
}
@@ -1236,10 +1271,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(src);
}
/*
@@ -1250,10 +1286,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(src);
}
#endif /* CFG_FLASH_PROTECTION */
--
1.5.3.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 5/6] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
@ 2007-12-11 15:35 ` Kumar Gala
2007-12-11 15:46 ` Haavard Skinnemoen
1 sibling, 1 reply; 25+ messages in thread
From: Kumar Gala @ 2007-12-11 15:35 UTC (permalink / raw)
To: u-boot
On Dec 11, 2007, at 9:28 AM, Haavard Skinnemoen wrote:
> 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 | 203 ++++++++++++++++++++++++++++
> +------------------
> 1 files changed, 125 insertions(+), 78 deletions(-)
>
> diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
> index a89fcae..70a626a 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,46 @@ 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)
> +{
> + *(volatile u8 *)addr = value;
> +}
> +
> +static void flash_write16(u16 value, void *addr)
> +{
> + *(volatile u16 *)addr = value;
> +}
> +
> +static void flash_write32(u32 value, void *addr)
> +{
> + *(volatile u32 *)addr = value;
> +}
> +
> +static void flash_write64(u64 value, void *addr)
> +{
> + *(volatile u64 *)addr = value;
> +}
> +
> +static u8 flash_read8(void *addr)
> +{
> + return *(volatile u8 *)addr;
> +}
> +
> +static u16 flash_read16(void *addr)
> +{
> + return *(volatile u16 *)addr;
> +}
> +
> +static u32 flash_read32(void *addr)
> +{
> + return *(volatile u32 *)addr;
> +}
> +
> +static u64 flash_read64(void *addr)
> +{
> + return *(volatile u64 *)addr;
> +}
> +
should these not use in/out macros from asm/io.h?
- k
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 6/6] cfi_flash: Use " Haavard Skinnemoen
@ 2007-12-11 15:36 ` Kumar Gala
2007-12-11 15:43 ` Haavard Skinnemoen
2007-12-11 22:10 ` Wolfgang Denk
1 sibling, 1 reply; 25+ messages in thread
From: Kumar Gala @ 2007-12-11 15:36 UTC (permalink / raw)
To: u-boot
On Dec 11, 2007, at 9:28 AM, Haavard Skinnemoen wrote:
> 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.
Just to clarify, would we have two mappings? one cacheable for normal
read operations and one non-cacheable for control access?
- k
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 15:36 ` Kumar Gala
@ 2007-12-11 15:43 ` Haavard Skinnemoen
2007-12-11 18:49 ` Stefan Roese
0 siblings, 1 reply; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:43 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 09:36:50 -0600
Kumar Gala <galak@kernel.crashing.org> wrote:
> On Dec 11, 2007, at 9:28 AM, Haavard Skinnemoen wrote:
>
> > 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.
>
> Just to clarify, would we have two mappings? one cacheable for normal
> read operations and one non-cacheable for control access?
Yeah, that would probably make sense. Should we have different
functions for them or add a "flags" parameter (which could also be used
to turn on more "advanced" options like write-combining)?
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 15:35 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Kumar Gala
@ 2007-12-11 15:46 ` Haavard Skinnemoen
2007-12-11 16:25 ` Wolfgang Denk
0 siblings, 1 reply; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 15:46 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 09:35:21 -0600
Kumar Gala <galak@kernel.crashing.org> wrote:
> should these not use in/out macros from asm/io.h?
That would probably be better. It's just that I'm having a hard time
finding a set of macros that
a) is available on all architectures
b) don't do any byte swapping or other tricks
__raw_writeb() and friends would satisfy b) but not a)...
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 15:46 ` Haavard Skinnemoen
@ 2007-12-11 16:25 ` Wolfgang Denk
2007-12-11 17:13 ` Haavard Skinnemoen
0 siblings, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2007-12-11 16:25 UTC (permalink / raw)
To: u-boot
In message <20071211164644.6430849a@dhcp-252-066.norway.atmel.com> you wrote:
> On Tue, 11 Dec 2007 09:35:21 -0600
> Kumar Gala <galak@kernel.crashing.org> wrote:
>
> > should these not use in/out macros from asm/io.h?
>
> That would probably be better. It's just that I'm having a hard time
> finding a set of macros that
> a) is available on all architectures
> b) don't do any byte swapping or other tricks
>
> __raw_writeb() and friends would satisfy b) but not a)...
Then we eventually should implement these for the missing
architetures.
Kumar is right. We definitely must use the "real" accessor functions.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
365 Days of drinking Lo-Cal beer. = 1 Lite-year
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 16:25 ` Wolfgang Denk
@ 2007-12-11 17:13 ` Haavard Skinnemoen
2007-12-11 18:59 ` Stefan Roese
2007-12-11 22:05 ` Wolfgang Denk
0 siblings, 2 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-11 17:13 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 17:25:22 +0100
Wolfgang Denk <wd@denx.de> wrote:
> In message <20071211164644.6430849a@dhcp-252-066.norway.atmel.com> you wrote:
> > On Tue, 11 Dec 2007 09:35:21 -0600
> > Kumar Gala <galak@kernel.crashing.org> wrote:
> >
> > > should these not use in/out macros from asm/io.h?
> >
> > That would probably be better. It's just that I'm having a hard time
> > finding a set of macros that
> > a) is available on all architectures
> > b) don't do any byte swapping or other tricks
> >
> > __raw_writeb() and friends would satisfy b) but not a)...
>
> Then we eventually should implement these for the missing
> architetures.
>
> Kumar is right. We definitely must use the "real" accessor functions.
Yeah, I agree too.
From a quick glance, m68k, powerpc, nios and nios2 lack these
functions. Anything special I need to know about those architectures,
or should I just grab them from Linux or use volatile?
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 15:43 ` Haavard Skinnemoen
@ 2007-12-11 18:49 ` Stefan Roese
2007-12-12 9:36 ` Haavard Skinnemoen
0 siblings, 1 reply; 25+ messages in thread
From: Stefan Roese @ 2007-12-11 18:49 UTC (permalink / raw)
To: u-boot
On Tuesday 11 December 2007, Haavard Skinnemoen wrote:
> > > 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.
> >
> > Just to clarify, would we have two mappings? one cacheable for normal
> > read operations and one non-cacheable for control access?
>
> Yeah, that would probably make sense. Should we have different
> functions for them or add a "flags" parameter (which could also be used
> to turn on more "advanced" options like write-combining)?
When starting something like map_physmem(), we should consider the following
things:
- Some platforms have >32bit physical address space, like PPC440 with 36bits.
So the type of phys_addr should not be fixed to u32. We need a new typedef
here. And/or perhaps something like the resource stuff from Linux.
- We should add a size parameter
- And a "flags" parameter as mentioned above would make sense too, for stuff
like caching etc.
And comments?
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] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 17:13 ` Haavard Skinnemoen
@ 2007-12-11 18:59 ` Stefan Roese
2007-12-11 22:05 ` Wolfgang Denk
1 sibling, 0 replies; 25+ messages in thread
From: Stefan Roese @ 2007-12-11 18:59 UTC (permalink / raw)
To: u-boot
On Tuesday 11 December 2007, Haavard Skinnemoen wrote:
> > > That would probably be better. It's just that I'm having a hard time
> > > finding a set of macros that
> > > a) is available on all architectures
> > > b) don't do any byte swapping or other tricks
> > >
> > > __raw_writeb() and friends would satisfy b) but not a)...
> >
> > Then we eventually should implement these for the missing
> > architetures.
> >
> > Kumar is right. We definitely must use the "real" accessor functions.
>
> Yeah, I agree too.
From a quick glance in the Linux mtd cfi driver, it looks like it boils down
to those __raw_writeb() and friends here too. So this should be a good choice
for U-Boot too.
> From a quick glance, m68k, powerpc, nios and nios2 lack these
> functions. Anything special I need to know about those architectures,
> or should I just grab them from Linux or use volatile?
Best would be to add the Linux variants from my point of view. If this gets
too complicated for you, since you can't know all those platforms by heart,
just add the volatile accesses for now and add a big comment in the header.
Then the maintainers/custodians should fix this later.
But we should really try to get all this great cfi rework accepted in this
merge window.
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] 25+ messages in thread
* [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups
2007-12-11 15:28 [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Haavard Skinnemoen
@ 2007-12-11 19:04 ` Stefan Roese
2007-12-12 10:01 ` Haavard Skinnemoen
1 sibling, 1 reply; 25+ messages in thread
From: Stefan Roese @ 2007-12-11 19:04 UTC (permalink / raw)
To: u-boot
Hi Haavard,
On Tuesday 11 December 2007, Haavard Skinnemoen wrote:
> This is a series of cleanups to the CFI driver I did while debugging
> why it refused to work on my AVR32 boards, rebased on top of the
> latest CFI custodian tree with "[PATCH] CFI: synchronize command
> offsets with Linux CFI driver" applied as well.
>
> I'm not completely done yet, as I need more fixes to make the CFI
> driver work on boards like the ATNGW100. But these initial patches are
> seriously painful to rebase (especially #3 in this series,) so I'd
> like some feedback from others if I'm moving in an acceptable
> direction with this.
Great work so far. Thanks.
> I've compile-tested the whole thing using MAKEALL on ppc (no point in
> testing on avr32 since no boards use this driver yet.) mcc200 failed,
> but it complains about lots of undefined symbols that has nothing to
> do with the CFI driver, so I'm pretty sure it isn't my fault.
No, I have seen this here today too. That's not related with your patch
series.
> Please let me know which parts of this are acceptable, and if there's
> something that can be done in a better way. And if you merge parts
> 1-3 (or even more of them), I'd be _very_ happy :-)
You have my ack at least on 1-3. And with a little rework I would gladly
accept all of your patches. Looks like a great improvement to me.
> There are a couple of remaining cleanups I'd like to make that go on
> top of this stuff, mostly related to refactoring the command set
> handling and adding manufacturer-specific fixups.
Good. Let's focus on your current patchset for now.
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] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 17:13 ` Haavard Skinnemoen
2007-12-11 18:59 ` Stefan Roese
@ 2007-12-11 22:05 ` Wolfgang Denk
2007-12-12 9:31 ` Haavard Skinnemoen
1 sibling, 1 reply; 25+ messages in thread
From: Wolfgang Denk @ 2007-12-11 22:05 UTC (permalink / raw)
To: u-boot
In message <20071211181317.7a9abc4e@dhcp-252-066.norway.atmel.com> you wrote:
>
> > Kumar is right. We definitely must use the "real" accessor functions.
>
> Yeah, I agree too.
>
> From a quick glance, m68k, powerpc, nios and nios2 lack these
> functions. Anything special I need to know about those architectures,
> or should I just grab them from Linux or use volatile?
Grabbing the code from Linux is fine with me; we must test this
extensively in any case. But I would not reject the patch if you made
life easy for you and just used volatile for these archs.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Life and death are seldom logical."
"But attaining a desired goal always is."
-- McCoy and Spock, "The Galileo Seven", stardate 2821.7
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 6/6] cfi_flash: Use " Haavard Skinnemoen
2007-12-11 15:36 ` Kumar Gala
@ 2007-12-11 22:10 ` Wolfgang Denk
2007-12-11 22:55 ` Andrew Dyer
2007-12-12 9:23 ` Haavard Skinnemoen
1 sibling, 2 replies; 25+ messages in thread
From: Wolfgang Denk @ 2007-12-11 22:10 UTC (permalink / raw)
To: u-boot
In message <1197386900-14570-7-git-send-email-hskinnemoen@atmel.com> you wrote:
> Use map_physmem() and unmap_physmem() to convert from physical to
> virtual addresses. This gives the arch a chance to provide an uncached
Virtual addresses? We don't have virtual memory in U-Boot...
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I'd rather be led to hell than managed to heaven.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 22:10 ` Wolfgang Denk
@ 2007-12-11 22:55 ` Andrew Dyer
2007-12-12 6:09 ` Stefan Roese
2007-12-12 9:23 ` Haavard Skinnemoen
1 sibling, 1 reply; 25+ messages in thread
From: Andrew Dyer @ 2007-12-11 22:55 UTC (permalink / raw)
To: u-boot
On Dec 11, 2007 4:10 PM, Wolfgang Denk <wd@denx.de> wrote:
> In message <1197386900-14570-7-git-send-email-hskinnemoen@atmel.com> you wrote:
> > Use map_physmem() and unmap_physmem() to convert from physical to
> > virtual addresses. This gives the arch a chance to provide an uncached
>
> Virtual addresses? We don't have virtual memory in U-Boot...
Virtual addesses don't imply demand paged virtual memory.
For example on MIPS all software addresses are virtual and go through
a translation to a physical address (granted for some regions of
memory it's just forcing some address bits). Some procs (Au1xxx) go
as far as to require using the TLB to access all of the 36-bit
physical space in the 32-bit virtual space. For u-boot we can usually
get away with a static mapping, but the mapping is still there.
--
Hardware, n.:
The parts of a computer system that can be kicked.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 22:55 ` Andrew Dyer
@ 2007-12-12 6:09 ` Stefan Roese
0 siblings, 0 replies; 25+ messages in thread
From: Stefan Roese @ 2007-12-12 6:09 UTC (permalink / raw)
To: u-boot
On Tuesday 11 December 2007, Andrew Dyer wrote:
> > Virtual addresses? We don't have virtual memory in U-Boot...
>
> Virtual addesses don't imply demand paged virtual memory.
>
> For example on MIPS all software addresses are virtual and go through
> a translation to a physical address (granted for some regions of
> memory it's just forcing some address bits). Some procs (Au1xxx) go
> as far as to require using the TLB to access all of the 36-bit
> physical space in the 32-bit virtual space. For u-boot we can usually
> get away with a static mapping, but the mapping is still there.
Right.
We already have this static mapping on most PPC440 platforms too. But here we
currently try to match the low 32bits of the physical and the "virtual"
address. How should we call such a resulting address if not "virtual
address"?
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] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 22:10 ` Wolfgang Denk
2007-12-11 22:55 ` Andrew Dyer
@ 2007-12-12 9:23 ` Haavard Skinnemoen
1 sibling, 0 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-12 9:23 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 23:10:40 +0100
Wolfgang Denk <wd@denx.de> wrote:
> In message <1197386900-14570-7-git-send-email-hskinnemoen@atmel.com> you wrote:
> > Use map_physmem() and unmap_physmem() to convert from physical to
> > virtual addresses. This gives the arch a chance to provide an uncached
>
> Virtual addresses? We don't have virtual memory in U-Boot...
That's for the CPU to decide, not you.
All pointers are fundamentally virtual addresses. It's just that lots
of code all over u-boot assume that virtual and physical addresses are
the same. This results in, I suspect, lots of platforms running with
caches disabled and therefore take longer to boot than necessary.
By introducing mapping functions like this, we allow drivers to tell
the platform exactly what kind of caching behavior they want, so the
platform can allow caches to be enabled for all the memory where I/O
consistency is not an issue (e.g. code and data memory.)
Platforms that don't want this (for example platforms with no MMU, no
caches and/or built-in I/O coherency) can just implement it as a cast
to void *, which is exactly what we're doing today. In other words, no
overhead for platforms that don't (need to) care.
Btw, MIPS and SH (at least some versions) have very similar default
virtual memory layout as AVR32, so I'm pretty sure this can benefit
more than one platform.
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors
2007-12-11 22:05 ` Wolfgang Denk
@ 2007-12-12 9:31 ` Haavard Skinnemoen
0 siblings, 0 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-12 9:31 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 23:05:37 +0100
Wolfgang Denk <wd@denx.de> wrote:
> In message <20071211181317.7a9abc4e@dhcp-252-066.norway.atmel.com> you wrote:
> >
> > > Kumar is right. We definitely must use the "real" accessor functions.
> >
> > Yeah, I agree too.
> >
> > From a quick glance, m68k, powerpc, nios and nios2 lack these
> > functions. Anything special I need to know about those architectures,
> > or should I just grab them from Linux or use volatile?
>
> Grabbing the code from Linux is fine with me; we must test this
> extensively in any case. But I would not reject the patch if you made
> life easy for you and just used volatile for these archs.
powerpc and m68k seem to use volatile in Linux too, so those are easy.
There's no nios/nios2 support in Linux, so I think I'll just go with
volatile for those as well. It should at least not break the CFI driver
since it uses volatile already.
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-11 18:49 ` Stefan Roese
@ 2007-12-12 9:36 ` Haavard Skinnemoen
2007-12-12 10:24 ` Stefan Roese
0 siblings, 1 reply; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-12 9:36 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 19:49:26 +0100
Stefan Roese <sr@denx.de> wrote:
> When starting something like map_physmem(), we should consider the following
> things:
>
> - Some platforms have >32bit physical address space, like PPC440 with 36bits.
> So the type of phys_addr should not be fixed to u32. We need a new typedef
> here. And/or perhaps something like the resource stuff from Linux.
Yeah, we probably need a typedef. How about phys_addr_t or something?
I can cook up a patch adding phys_addr_t typedef'd as unsigned long on
all architectures. If someone wants something different, please let me
know.
> - We should add a size parameter
Absolutely.
> - And a "flags" parameter as mentioned above would make sense too, for stuff
> like caching etc.
Agreed. Platforms are of course free to ignore these extra parameters.
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups
2007-12-11 19:04 ` [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Stefan Roese
@ 2007-12-12 10:01 ` Haavard Skinnemoen
0 siblings, 0 replies; 25+ messages in thread
From: Haavard Skinnemoen @ 2007-12-12 10:01 UTC (permalink / raw)
To: u-boot
On Tue, 11 Dec 2007 20:04:05 +0100
Stefan Roese <sr@denx.de> wrote:
> > Please let me know which parts of this are acceptable, and if there's
> > something that can be done in a better way. And if you merge parts
> > 1-3 (or even more of them), I'd be _very_ happy :-)
>
> You have my ack at least on 1-3. And with a little rework I would gladly
> accept all of your patches. Looks like a great improvement to me.
Great, thanks. I'll get working on the suggestions I got so far and
post an updated series (excluding 1-3.)
Haavard
^ permalink raw reply [flat|nested] 25+ messages in thread
* [U-Boot-Users] [PATCH 6/6] cfi_flash: Use map_physmem() and unmap_physmem()
2007-12-12 9:36 ` Haavard Skinnemoen
@ 2007-12-12 10:24 ` Stefan Roese
0 siblings, 0 replies; 25+ messages in thread
From: Stefan Roese @ 2007-12-12 10:24 UTC (permalink / raw)
To: u-boot
On Wednesday 12 December 2007, Haavard Skinnemoen wrote:
> > When starting something like map_physmem(), we should consider the
> > following things:
> >
> > - Some platforms have >32bit physical address space, like PPC440 with
> > 36bits. So the type of phys_addr should not be fixed to u32. We need a
> > new typedef here. And/or perhaps something like the resource stuff from
> > Linux.
>
> Yeah, we probably need a typedef. How about phys_addr_t or something?
ACK.
> I can cook up a patch adding phys_addr_t typedef'd as unsigned long on
> all architectures. If someone wants something different, please let me
> know.
Yes, start with "unsigned long" and the platform maintainer can fix this later
if needed. This way we can get this started right now.
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] 25+ messages in thread
* [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 2/6] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
@ 2007-12-13 11:04 ` Stefan Roese
1 sibling, 0 replies; 25+ messages in thread
From: Stefan Roese @ 2007-12-13 11:04 UTC (permalink / raw)
To: u-boot
On Tuesday 11 December 2007, Haavard Skinnemoen wrote:
> 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.)
I'm trying to apply your patches now but "git-am" fails:
[stefan at ubuntu u-boot-cfi-flash (master)]$ git-am \[PATCH\ 1_6\]\ cfi_flash\:\
Break\ long\ lines.mbox
Applying cfi_flash: Break long lines
error: patch failed: drivers/mtd/cfi_flash.c:1204
error: drivers/mtd/cfi_flash.c: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git-am --resolved".
If you would prefer to skip this patch, instead run "git-am --skip".
Could you please resolve this issue and resend the patch series? I just pushed
the latest change from Bartlomiej Sieka into the cfi-flash master repo.
Please rebase against this.
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] 25+ messages in thread
end of thread, other threads:[~2007-12-13 11:04 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-11 15:28 [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 2/6] cfi_flash: Make some needlessly global functions static Haavard Skinnemoen
[not found] ` <1197386900-14570-4-git-send-email-hskinnemoen@atmel.com>
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 5/6] Introduce map_physmem() and unmap_physmem() Haavard Skinnemoen
2007-12-11 15:28 ` [U-Boot-Users] [PATCH 6/6] cfi_flash: Use " Haavard Skinnemoen
2007-12-11 15:36 ` Kumar Gala
2007-12-11 15:43 ` Haavard Skinnemoen
2007-12-11 18:49 ` Stefan Roese
2007-12-12 9:36 ` Haavard Skinnemoen
2007-12-12 10:24 ` Stefan Roese
2007-12-11 22:10 ` Wolfgang Denk
2007-12-11 22:55 ` Andrew Dyer
2007-12-12 6:09 ` Stefan Roese
2007-12-12 9:23 ` Haavard Skinnemoen
2007-12-11 15:35 ` [U-Boot-Users] [PATCH 4/6] cfi_flash: Introduce read and write accessors Kumar Gala
2007-12-11 15:46 ` Haavard Skinnemoen
2007-12-11 16:25 ` Wolfgang Denk
2007-12-11 17:13 ` Haavard Skinnemoen
2007-12-11 18:59 ` Stefan Roese
2007-12-11 22:05 ` Wolfgang Denk
2007-12-12 9:31 ` Haavard Skinnemoen
2007-12-13 11:04 ` [U-Boot-Users] [PATCH 1/6] cfi_flash: Break long lines Stefan Roese
2007-12-11 19:04 ` [U-Boot-Users] [PATCH 0/6] cfi_flash cleanups Stefan Roese
2007-12-12 10:01 ` Haavard Skinnemoen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox