public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* CFI JEDEC probing
@ 2001-06-11 16:42 Stuart Menefy
  2001-06-12  8:34 ` David Woodhouse
  0 siblings, 1 reply; 2+ messages in thread
From: Stuart Menefy @ 2001-06-11 16:42 UTC (permalink / raw)
  To: linux-mtd

[-- Attachment #1: Type: text/plain, Size: 1323 bytes --]

Folks

I think I've come across a limitation in the CFI JEDEC proving code.

I'm working with four ST M29W160DT devices, mapped as follows:

x               data bus
x
x           D31    D16   D15     D0
x            |      |     |      |
x            |      |     |      |
x        0 +----------+ +----------+
x          |D15     D0| |D15     D0|
x          |          | |          |
x   3fffff |          | |          |
x          +----------+ +----------+
x            |      |     |      |
x   400000 +----------+ +----------+
x          |D15     D0| |D15     D0|
x          |          | |          |
x   7fffff |          | |          |
x          +----------+ +----------+
x

Humm, not sure if that makes things clearer or not! What I'm trying to
say is, four 16 bit devices, on a 32bit data bus, with an interleave
of 2, mapped into contiguous memory locations.

When probing for the first two devices, the code in cfi_jedec_lookup()
only appears to only be able to handle an interleave of 1.

I've added code which works for me and generates the appropriate
device and manufacturer ID's, based on the bus width and interleave,
for comparison with the values read back from the Flash devices.
A copy of the code is attached. Do you think this is generally useful,
or have I missed something obvious?

Thanks

Stuart

[-- Attachment #2: Text --]
[-- Type: text/plain , Size: 2834 bytes --]

Index: drivers/mtd/chips/cfi_jedec.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_jedec.c,v
retrieving revision 1.5
diff -c -r1.5 cfi_jedec.c
*** drivers/mtd/chips/cfi_jedec.c	2001/06/02 14:52:23	1.5
--- drivers/mtd/chips/cfi_jedec.c	2001/06/11 16:39:37
***************
*** 246,261 ****
  	} 
  };
  
! int cfi_jedec_lookup(int index, int mfr_id, int dev_id)
  {
    	if (index>=0){
! 		if (jedec_table[index].mfr_id == mfr_id &&
! 		    jedec_table[index].dev_id == dev_id) return index;
    	}
    	else{
  		for (index=0; jedec_table[index].mfr_id; index++){
! 		    if (jedec_table[index].mfr_id == mfr_id &&
! 		        jedec_table[index].dev_id == dev_id) return index;
  		}
    	}
  	return -1;
--- 246,304 ----
  	} 
  };
  
! /*
!  * Transforms the ID for the given geometry (bus width & interleave).
!  * This is a slightly modified version of cfi_build_cmd, in that it copes
!  * with truncating down a 16 bit ID to 8 bits when required.
!  */
! static __u32 cfi_build_id(__u16 id, struct map_info *map, int interleave)
  {
+ 	__u32 val = 0;
+ 
+ 	if (cfi_buswidth_is_1()) {
+ 		/* 1 x8 device */
+ 		val = id & 0xff;
+ 	} else if (cfi_buswidth_is_2()) {
+ 		if (cfi_interleave_is_1()) {
+ 			/* 1 x16 device in x16 mode */
+ 			val = cpu_to_cfi16(id);
+ 		} else if (cfi_interleave_is_2()) {
+ 			/* 2 (x8, x16 or x32) devices in x8 mode */
+ 			id &= 0xff;
+ 			val = cpu_to_cfi16((id << 8) | id);
+ 		}
+ 	} else if (cfi_buswidth_is_4()) {
+ 		if (cfi_interleave_is_1()) {
+ 			/* 1 x32 device in x32 mode */
+ 			val = cpu_to_cfi32(id);
+ 		} else if (cfi_interleave_is_2()) {
+ 			/* 2 x16 device in x16 mode */
+ 			val = cpu_to_cfi32((id << 16) | id);
+ 		} else if (cfi_interleave_is_4()) {
+ 			/* 4 (x8, x16 or x32) devices in x8 mode */
+ 			id &= 0xff;
+ 			val = (id << 16) | id;
+ 			val = cpu_to_cfi32((val << 8) | val);
+ 		}
+ 	}
+ 	return val;
+ }
+ 
+ int cfi_jedec_lookup(int index, int mfr_id, int dev_id, struct map_info *map, int interleave)
+ {
+ 	printk("buswidth %d, interleave %d\n", map->buswidth, interleave);
    	if (index>=0){
! 		const __u32 dev_mfr_id = cfi_build_id(jedec_table[index].mfr_id, map, interleave);
! 		const __u32 dev_dev_id = cfi_build_id(jedec_table[index].dev_id, map, interleave);
! 		if (dev_mfr_id == mfr_id && dev_dev_id == dev_id) return index;
    	}
    	else{
  		for (index=0; jedec_table[index].mfr_id; index++){
! 		    const __u32 dev_mfr_id = cfi_build_id(jedec_table[index].mfr_id, map, interleave);
! 		    const __u32 dev_dev_id = cfi_build_id(jedec_table[index].dev_id, map, interleave);
! 		    printk("Comp %08x %08x and %08x %08x\n",
! 			   dev_mfr_id, mfr_id, dev_dev_id, dev_id);
! 		    if (dev_mfr_id == mfr_id && dev_dev_id == dev_id) return index;
  		}
    	}
  	return -1;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: CFI JEDEC probing
  2001-06-11 16:42 CFI JEDEC probing Stuart Menefy
@ 2001-06-12  8:34 ` David Woodhouse
  0 siblings, 0 replies; 2+ messages in thread
From: David Woodhouse @ 2001-06-12  8:34 UTC (permalink / raw)
  To: Stuart Menefy; +Cc: linux-mtd

Stuart.Menefy@st.com said:
>  Humm, not sure if that makes things clearer or not! What I'm trying
> to say is, four 16 bit devices, on a 32bit data bus, with an
> interleave of 2, mapped into contiguous memory locations. 

Take a look at the patch that Jan Rovins posted on Thursday for the MCPN765 
board. It deals with it in a different way - by acknowledging that what you 
effectively have is a 64-bit bus.

The alternative is to deal with the flash as two entirely separate 32-bit 
pairs, and just have two separate map drivers giving access to even and odd 
words respectively.

I'd like to see the cfi_jedec code removed completely and JEDEC probing put 
in a separate probe function, rather than more special cases added to it.


--
dwmw2

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-06-12  8:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-06-11 16:42 CFI JEDEC probing Stuart Menefy
2001-06-12  8:34 ` David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox