2009-07-29 11:34:50     multiple parallel NOR flashes on only one AMS (AMS0)

Document created by Aaronwu Employee on Aug 16, 2013
Version 1Show Document
  • View in full screen mode

2009-07-29 11:34:50     multiple parallel NOR flashes on only one AMS (AMS0)

Konstantin Hartwich (GERMANY)

Message: 78170   


hi there,


again a tricky thing to manage.


the AMS map window of 1 M is just too small for most parallel flash types, thats clear, that why, thanks to you guys we have that neat gpio-addr-flash.c map driver. it works great, even having it utilize only one AMS line, setting its map window to 0x20000000 to 0x200FFFFF, and using i.e. PG8, PG9, PG10 in the GPIO struct in the board file for the GPIO assisted flash driver. well, it works in this config for an up to 8 M flash..thats perfectly fine, having one chip only..so the driver probes one at the beginnging of the map window.


but, what about having 2 of those CFI chips of 4M (whereby their respective /CS are dispatched in an FPGA), in same situation,


covering just about the same memory range of 0x20000000 to 0x20800000.. but only using AMS0 i.e.


is there a possibility to specify somehow, to the driver "look again in the map window,  but this time, use another offset (0x400000 i.e) to detect a second chip."


or isn't it even possible to have 2 gpio-addr-flash driver instances running at once, each with different mappings?


any idea on that? or do i have to hack the gpio driver to support multiple chips by myself?




PS: idea behind that is: I have a outdated board, with some dirty hacked driver accessing in that same manner 2 parallel NOR flashes and i want to port to clean APIs now..its a bunch of work, but definitly worth the bother, if staying in sync is possible, especially if one has means of providing easy to update images for u-boot, linux, and even programs or filesystems..




2009-07-29 17:06:39     Re: multiple parallel NOR flashes on only one AMS (AMS0)


Message: 78177   




I think what you are suggesting will work - but the person who wrote/maintains this driver is out for a bit. He will respond when he gets back.






2009-07-29 18:12:37     Re: multiple parallel NOR flashes on only one AMS (AMS0)

Konstantin Hartwich (GERMANY)

Message: 78178   


thanks robin,


i took a compare-look into the physmap.c and the gpio-addr-flash.c, and it seems that physmap.c *is* supporting multiple chips. but the gpio driver only can handle *one* chip..a streching to multiple chips might be possible, but one might need to think of a general way to do this and specify a common partition table, while also specifying the chip map alignment, since my case seems to be special, due the following:


1. the handling real window is same for both chips. 0x20000000 - 0x200FFFFF plus the additional GPIOs.


2. probing first chip would probe it for the total map size (current state in gpio-addr-flash.c) and reduce it to the the real chip size. probing the second chip would need to twiddle it on before, and then probe. it is to say "look for the first chip in the total window specified (0x20000000-0x207FFFFF), which would assert the right AMS signal to select it, and then look for the second chip in the virtual window 0x20400000-0x207FFFFF, which is rather dumb.


so there needs to be kind of a seperate spicification, which would lead to a redesign of the driver itself. someting like




static unsigned cm_flash_gpios[] = { GPIO_PG8, GPIO_PG9, GPIO_PG10 };


static struct resource cm_flash_resource[] = {


        .name  = 0, //the twiddeling window, we use only 1 MB, for calculation only

        .start = 0x20000000,

        .end   = 0x200fffff,

        .flags = IORESOURCE_MEM, //may be use something else to differ from the 2 down there,

    }, {

        .name  = "cfi_probe", //a first flash, goes to do_map_probe

        .start = 0x20000000,

        .end   = 0x203fffff,

        .flags = IORESOURCE_MEM,

    }, {

        .name  = "cfi_probe", //a second flash, goes to do_map_probe

        .start = 0x20400000,

        .end   = 0x207fffff,

        .flags = IORESOURCE_MEM,

    }, {

        .start = (unsigned long)cm_flash_gpios,

        .end   = ARRAY_SIZE(cm_flash_gpios),

        .flags = IORESOURCE_IRQ,




after looking on it, i doubt that the current driver can support that just like that. i 'll try to extend the current one, just in case it should work, i'll surly post it here. maybe it can find its way into the kernel


nevertheless, the guy who manages that is welcome with any hints.


thanks robin




2009-08-02 17:59:25     Re: multiple parallel NOR flashes on only one AMS (AMS0)

Konstantin Hartwich (GERMANY)

Message: 78273   


ok guys, i found the solution..


but i had a different situation to start at. the FPGA was programmed in a way that the second flash listens on AMS1, so it is bit esier. but even in having the flash listening on same AMS, at least under u-boot, it would have worked out.


now thats the summery.


flash 1: S29GL320A90 , 2M * 16 Bit = 4MB


physical adress: listens on AMS0, 0x20000000, should map to virtual 0x20000000 - 0x203FFFFF


flash 2: same type,


physical adress: AMS1, 0x20100000, should map to virtual 0x20400000 0x207FFFFF


you have to use the GPIOs, to help here, the driver can be ported from tcm-bf537.c or something. i used PG8,PG9,PG10 to adress the 8 M


u-boot: set config file to:




#define CONFIG_SYS_FLASH_BASE        0x20000000





/* some have 67 sectors (M29W320DB), but newer have 71 (M29W320EB) */ //needs to have double, since we have 2 flashes




!!CAUTION: FLASH_SECT need to have 142 instead of 71, it wont work otherwise, it took me a while to figure out that i can specify 2 banks of flash, and 2 different bases...




and in the gpio_cfi_flash.c: something like the following


#define GPIO_PIN_1  PG0

#define GPIO_MASK_1 (1 << 20)

#define GPIO_PIN_2  PG1

#define GPIO_MASK_2 (1 << 21)

#define GPIO_PIN_3  PG2

#define GPIO_MASK_3 (1 << 22)



//we need this somehow from the flash detection

#define FLASH_SIZE 0x400000


void *gpio_cfi_flash_swizzle(void *vaddr)


    unsigned long addr = (unsigned long)vaddr;

    unsigned long addr2 = addr;


    if (addr & GPIO_MASK_1)





#ifdef GPIO_MASK_2

    if (addr & GPIO_MASK_2)






#ifdef GPIO_MASK_3

    if (addr & GPIO_MASK_3)







    //printf("swizzle %X to %X\n", vaddr, (addr & ~GPIO_MASK));

    //return (void *)(addr & ~GPIO_MASK);


    addr &= ~GPIO_MASK; //reverts back to BASE ADRESS + 1M Window

    if(addr2 >= 0x20400000)


        addr |= 0x20100000; //set to second flash, if we pass size of first



    return (void*)addr;





for LINUX:


the gpio driver could be used, but i needed to specify a second instance of it in the board file, without the need to change the gpio driver it self. the instance id should be set from id = 0 to id = 1, and the gpios could be used from the first driver.


but the window adress is in first instance 0x20000000-0x200FFFFF, in second one 0x20100000-0x201FFFFF. under linux we can comfortely access the flash under /dev/mtdblock*, without the need of dealing with the extended adresses.








under u-boot:


using same config setup as above, only the board specific gpio_cfi_flash.c driver needs the change, here we dont reset to 0x201XXXXX when passing the size limit of first flash, and simply really use the 3rd GPIO, and TADA, it works. the whole 0x20000000 - 0x207FFFFF span.




under LINUX:


here, the GPIO driver cant be used anymore. one could think, specifying the same windowsize for the second instance and having the driver deal with a different start offset for the whole  MTD partition setup (offset = 0x400000, beeing the size of the first, preceeding flash) the driver would map it correclty, i havent tried it out..you might try it.




hope this helps a bit




2009-08-12 00:44:26     Re: multiple parallel NOR flashes on only one AMS (AMS0)

Mike Frysinger (UNITED STATES)

Message: 78701   


so are you all set ?  or did you still need clarification on something ?