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..
QuoteReplyEditDelete
2009-07-29 17:06:39 Re: multiple parallel NOR flashes on only one AMS (AMS0)
Robin Getz (UNITED STATES)
Message: 78177
Konstantin:
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.
-Robin
QuoteReplyEditDelete
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
QuoteReplyEditDelete
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_FLASH_CFI_DRIVER
#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
#define CONFIG_SYS_FLASH_BASE 0x20000000
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_SYS_FLASH_PROTECTION
#define CONFIG_SYS_MAX_FLASH_BANKS 2
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, 0x20400000 }
/* some have 67 sectors (M29W320DB), but newer have 71 (M29W320EB) */ //needs to have double, since we have 2 flashes
#define CONFIG_SYS_MAX_FLASH_SECT 142
!!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)
#define GPIO_MASK (GPIO_MASK_1 | GPIO_MASK_2 | GPIO_MASK_3)
//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)
bfin_write_PORTGIO_SET(GPIO_PIN_1);
else
bfin_write_PORTGIO_CLEAR(GPIO_PIN_1);
#ifdef GPIO_MASK_2
if (addr & GPIO_MASK_2)
bfin_write_PORTGIO_SET(GPIO_PIN_2);
else
bfin_write_PORTGIO_CLEAR(GPIO_PIN_2);
#endif
#ifdef GPIO_MASK_3
if (addr & GPIO_MASK_3)
bfin_write_PORTGIO_SET(GPIO_PIN_3);
else
bfin_write_PORTGIO_CLEAR(GPIO_PIN_3);
#endif
SSYNC();
//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.
FOR THE CASE OF AMS0 TO BOTH FLASHES:
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
QuoteReplyEditDelete
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 ?