All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Schwingen <rincewind@discworld.dascon.de>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] Mixing CFI and non-CFI flashs?
Date: Sat, 3 Nov 2007 16:00:56 +0100	[thread overview]
Message-ID: <20071103150055.GA17224@discworld.dascon.de> (raw)
In-Reply-To: <200711030813.40329.sr@denx.de>

On Sat, Nov 03, 2007 at 08:13:40AM +0100, Stefan Roese wrote:
> I remember a discussion we had a while ago, about supporting non-CFI chips in 
> a common driver, but I can't find the mails right now. IIRC, the idea was to 
> add something close to the Linux JEDEC probe 
> (drivers/mtd/chips/jedec_probe.c) for this.

Good idea. I currently hard-coded the flash parameters for the boot flash,
since I know there is exactly one type on the boards, but having
jedec-probing would be nicer.

I think the CFI driver is a good start as a framework - all the
infrastructure for handling mutliple banks, different chip/bus mappings etc.
is there and could be used by jedec-flash code. For now, it is probably
easiest to add the JEDEC code to cfi_flash.c, to get access to the static
functions defined there, and then later split it out if necessary.

> I suggest that you post your current version for review. This sounds like a 
> start in the correct direction.

Fine. Here is what I have got now - it works for my board, but would
probably need some cleanup/renaming of symbols. The basic idea is that the
board-specific code provides a function "flash_detect_legacy" that is called
for every flash bank, which can provide hardcoded (or in the future
jedec-probed) flash information. If the function returns 0, the normal CFI
code is called.

Since that code is board-specific anyway, I think the board-specific code
can supply the information about chipwidth, buswidth etc. - there is no real
benefit in autoprobing these, and there is less probability for problems
(like 8-bit accesses to a 16-bit bus causing problems, etc.).


I have included one non-conditional patch I made:
@@ -1282,6 +1310,8 @@ ulong flash_get_size (ulong base, int banknum)
which causes the CFI code to stop in case CFG_MAX_FLASH_SECT is defined too
small - without that patch, u-boot overwrites other data and crashes
silently during startup. 

cu
Michael

Signed-off-by: Michael Schwingen <michael@schwingen.org>

diff --git a/include/flash.h b/include/flash.h
index b0bf733..f0ef6f7 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -101,6 +101,11 @@ extern void flash_read_user_serial(flash_info_t * info,
void * buffer, int offse
 extern void flash_read_factory_serial(flash_info_t * info, void * buffer,
int offset, int len);
 #endif /* CFG_FLASH_PROTECTION */
 
+#ifdef CFG_FLASH_CFI_LEGACY
+extern ulong flash_detect_legacy(ulong base, int banknum);
+#define CFI_CMDSET_AMD_LEGACY          0xFFF0
+#endif
+
 /*-----------------------------------------------------------------------
  * return codes from flash_write():
  */


diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
index 5579a1e..20ccc3a 100644
--- a/drivers/cfi_flash.c
+++ b/drivers/cfi_flash.c
@@ -345,7 +345,13 @@ unsigned long flash_init (void)
 	/* Init: no FLASHes known */
 	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
 		flash_info[i].flash_id = FLASH_UNKNOWN;
-		size += flash_info[i].size = flash_get_size (bank_base[i], i);
+
+#ifdef CFG_FLASH_CFI_LEGACY
+		flash_info[i].size = flash_detect_legacy (bank_base[i], i);
+		if (flash_info[i].size == 0)
+#endif
+		flash_info[i].size = flash_get_size (bank_base[i], i);
+		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",
@@ -488,6 +494,16 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 				flash_unlock_seq (info, sect);
 				flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
 				break;
+#ifdef CFG_FLASH_CFI_LEGACY
+			case CFI_CMDSET_AMD_LEGACY:
+				flash_write_cmd (info, 0,    0x5555, AMD_CMD_UNLOCK_START);
+				flash_write_cmd (info, 0,    0x2AAA, AMD_CMD_UNLOCK_ACK);
+				flash_write_cmd (info, 0,    0x5555, AMD_CMD_ERASE_START);
+				flash_write_cmd (info, 0,    0x5555, AMD_CMD_UNLOCK_START);
+				flash_write_cmd (info, 0,    0x2AAA, AMD_CMD_UNLOCK_ACK);
+				flash_write_cmd (info, sect, 0,      AMD_CMD_ERASE_SECTOR);
+				break;
+#endif
 			default:
 				debug ("Unkown flash vendor %d\n",
 				       info->vendor);
@@ -518,8 +534,12 @@ void flash_print_info (flash_info_t * info)
 
 	printf ("CFI conformant FLASH (%d x %d)",
 		(info->portwidth << 3), (info->chipwidth << 3));
-	printf ("  Size: %ld MB in %d Sectors\n",
-		info->size >> 20, info->sector_count);
+	if (info->size < 1024*1024)
+		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 ("  ");
 	switch (info->vendor) {
 		case CFI_CMDSET_INTEL_STANDARD:
@@ -534,6 +554,11 @@ void flash_print_info (flash_info_t * info)
 		case CFI_CMDSET_AMD_EXTENDED:
 			printf ("AMD Extended");
 			break;
+#ifdef CFG_FLASH_CFI_LEGACY
+		case CFI_CMDSET_AMD_LEGACY:
+			printf ("AMD (non-CFI)");
+			break;
+#endif
 		default:
 			printf ("Unknown (%d)", info->vendor);
 			break;
@@ -777,6 +802,9 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
 		break;
 	case CFI_CMDSET_AMD_STANDARD:
 	case CFI_CMDSET_AMD_EXTENDED:
+#ifdef CFG_FLASH_CFI_LEGACY
+	case CFI_CMDSET_AMD_LEGACY:
+#endif
 		retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
 		break;
 	default:
@@ -1282,6 +1310,8 @@ ulong flash_get_size (ulong base, int banknum)
 			debug ("erase_region_count = %d erase_region_size = %d\n",
 				erase_region_count, erase_region_size);
 			for (j = 0; j < erase_region_count; j++) {
+				if (sect_cnt >= CFG_MAX_FLASH_SECT)
+					break;
 				info->start[sect_cnt] = sector;
 				sector += (erase_region_size * size_ratio);
 
@@ -1387,6 +1417,12 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 		flash_unlock_seq (info, 0);
 		flash_write_cmd (info, 0, AMD_ADDR_START, AMD_CMD_WRITE);
 		break;
+#ifdef CFG_FLASH_CFI_LEGACY
+	case CFI_CMDSET_AMD_LEGACY:
+		flash_write_cmd (info, 0, 0x5555, AMD_CMD_UNLOCK_START);
+		flash_write_cmd (info, 0, 0x2AAA, AMD_CMD_UNLOCK_ACK);
+		flash_write_cmd (info, 0, 0x5555, AMD_CMD_WRITE);
+#endif
 	}
 
 	switch (info->portwidth) {





and then in the board-init code:

extern flash_info_t flash_info[];
#define AMD_CMD_RESET			0xF0

ulong flash_detect_legacy(ulong base, int banknum)
{
	if (banknum == 0) {
		flash_info_t *info = &flash_info[banknum];
		int i;
		unsigned long sector;

		info->portwidth = 1;
		info->chipwidth = 1;
		info->ext_addr = 0;
		info->cfi_version = 0;
		info->legacy_unlock = 0;
		info->start[0] = base;
		info->cmd_reset = AMD_CMD_RESET;
		info->vendor = CFI_CMDSET_AMD_LEGACY;
		info->flash_id = FLASH_MAN_CFI;

		info->sector_count = 64;

		for (i = 0, sector = base; i < info->sector_count; i++) {
			info->protect[i] = 0;
			info->start[i] = sector;
			sector += 4096;
		}

		info->buffer_size = 1;
		info->erase_blk_tout = 10000;
		info->buffer_write_tout = 1000;
		info->write_tout = 100;
		return 256*1024;
	}
	else
		return 0;
}

  reply	other threads:[~2007-11-03 15:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-02 20:53 [U-Boot-Users] Mixing CFI and non-CFI flashs? Michael Schwingen
2007-11-03  7:13 ` Stefan Roese
2007-11-03 15:00   ` Michael Schwingen [this message]
2007-11-05 11:21     ` Stefan Roese
2007-11-05 23:24       ` Michael Schwingen
2007-11-06  7:48         ` Stefan Roese
2007-11-06  8:26           ` Michael Schwingen
2007-11-06  8:59             ` Stefan Roese
2007-11-12 20:19               ` Michael Schwingen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071103150055.GA17224@discworld.dascon.de \
    --to=rincewind@discworld.dascon.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.